Discussão sobre Produtos NI

cancelar
Mostrando resultados para 
Pesquisar então 
Você quer dizer: 

paralelismo - medidor largura

Olá amigos.

 

Gostaria de executar três loops, cada um em velocidades diferentes. Também ter um unico botão de stop.

No meu projeto em anexo estou utilizando variavel local mas o processamento está muito lento.

Criticas serão bem vindas para todo o código.

 

Obrigado,

Aexandre.

Baixar tudo
0 Kudos
Mensagem 1 de 10
43.952Exibições

Boa Tarde Alexandre. tudo bom?

 

Eu olhei o código que você postou aqui e estou o retornando com alguns comentários e sugestões pontuais.

 

Na verdade o impacto das variáveis locais em questão de memória no seu código não seriam muito problema, o que mais me preocupa aí é que está faltando um pouco de estruturação no seu código e isso pode estar impactando muito no desempenho do seu código.

 

Pelo que eu vi de sua aplicação, seu projeto realiza as seguintes tarefas:

 

  • Adquirir dados de uma câmera
  • Processar esses dados,
  • Apresentar os dados para o usuário
  • Realizar log de dados

 

Se for isso, temos aí um típico caso de tarefas Produtoras e Consumidoras de dados. Olhando para as tarefas que descrevi em cima, poderíamos separá-las como

 

Produtores

  • Adquirir dados de uma câmera

Consumidores

  • Processar esses dados,
  • Apresentar os dados para o usuário
  • Realizar log de dados

É interessante separarmos essas tarefas, pois elas executam em taxas diferentes e não podem depender uma da outra (A aquisição não pode esperar que o processamento e o Log sejam feitos). Assim, teríamos que criar 2 loops diferentes para colacar essas tarefas e criar um mecanismo de comunicação que possa transferir os dados entre os dois loops sem perdas.

 

Para esse tipo de trasferencia, as Queues (Filas) são o mecanismo mais indicado.

 

Sendo assim, teríamos o seguinte diagrama simplificado do programa.

 

 

Capture.png

 

Para solucionar este tipo de problema de software, podemos aplicar o padrão de projeto Produtor/Consumidor, que trás para o código gráfico no LabVIEW algo bem próximo do que está no desenho. Dê uma olhada:

 

Producer_Consumer_20120919143003.png

 

Então, em resumo:

 

  1. Olhe as anotações que eu coloquei no seu código;
  2. Estude este padrão de projeto e tente colocar seu código nela.

Tenho certeza que fazendo isso, seu código vai ficar muito leve e funcional

 

Atenciosamente.

Felipe Flores
Technical Support Engineer
National Instruments
0 Kudos
Mensagem 2 de 10
43.942Exibições

Olá Felipe

Primeiramente gostaria de agradecer a atenção. Respondendo às perguntas:

Por que seu painel frontal ...? Uma parte é interface do operador e outra para a manutenção do sistema. Vou seguir seu conselho utilizando o Tab.

 

Por que usar a variável local...? Estava utilizando diretamente, mas devido ao loop ser temporizado em 2min para o log, ao acionar a chave liga datalog o indicador luminoso demorava 2min para acender.

 

As três medidas são iguais? Então por que...? Estou enviando cada uma para um loop. Não sei se é possível duplicar a variável local.

 

Por que isso somar zero? Antes estava ligando a vi com um offset diferente de zero. Depois de ajustado os cálculos ficou desnecessário; vou deletar.

 

Porque cada loop tem uma temporização...? Para o log, display e gráfico tenho necessidades de exibição em tempos diferentes.

 

Você está mostrando...? Por quê? Preciso exibir as duas bordas para possibilitar o ajuste de foco, filtro e etc. Gostaria de configurar os indicadores para detectar e mostrar a borda automaticamente.

-----------------------------------------

Quanto ao log de dados, eu deveria liga-lo somente quando fosse gravar algum dado ao invés de deixar o flag enable em true o tempo todo? Poderia dar um exemplo de escrita em baixo nível? Quanto a Queues nunca utilizei; você tem um código de exemplo?

Seguindo suas orientações, vou alocar a aquisição de imagem em um (while) loop. O restante (log, calculo, display e gráfico) ficariam em outro(s) loops. Mas como conseguirei o processamento paralelo dos loops? E qual a melhor forma de ajustar a velocidade para o log, calculo, display e gráfico nos valores que desejo?

 

Obrigado,

Alexandre.

0 Kudos
Mensagem 3 de 10
43.930Exibições

Olá Alexandre,

 

Me desculpe pela demora, Fiquei OOO durante um bom tempo. Vamos as respostas:

 

Por que seu painel frontal ...? Uma parte é interface do operador e outra para a manutenção do sistema. Vou seguir seu conselho utilizando o Tab.

 

Sim! me parece uma boa solução usar abas para este projeto

 

Por que usar a variável local...? Estava utilizando diretamente, mas devido ao loop ser temporizado em 2min para o log, ao acionar a chave liga datalog o indicador luminoso demorava 2min para acender.

 

Então. Na verdade o Loop de log não deveria ser temporizado assim! Você está fazendo uma Temporização de Execução em vez de Temporização de Software. Veja a diferença entre os dois neste link.

 

As três medidas são iguais? Então por que...? Estou enviando cada uma para um loop. Não sei se é possível duplicar a variável local.

 

É possível sim, mas não indicado. Existem métodos em que não é necessário usá-las, mas é preciso mudar a estrutura do código.

 

Por que isso somar zero? Antes estava ligando a vi com um offset diferente de zero. Depois de ajustado os cálculos ficou desnecessário; vou deletar.

 

OK!

 

Porque cada loop tem uma temporização...? Para o log, display e gráfico tenho necessidades de exibição em tempos diferentes.

 

Do log tudo bem, mas você precisa realmente que o gráfico e o display tenham temporizações diferentes? Por quê?

 

OBS: Seu log precisa gravar só um valor (O mais recente) a cada 5 min. ou você precisa gravar todos os resultados?

 

Você está mostrando...? Por quê? Preciso exibir as duas bordas para possibilitar o ajuste de foco, filtro e etc. Gostaria de configurar os indicadores para detectar e mostrar a borda automaticamente.

 

OK!

 

-----------------------------------------

 

Quanto ao log de dados, eu deveria liga-lo somente quando fosse gravar algum dado ao invés de deixar o flag enable em true o tempo todo? Poderia dar um exemplo de escrita em baixo nível? Quanto a Queues nunca utilizei; você tem um código de exemplo?

 

Você pode faze a temporização de software como mostrado no link que eu citei acima. Não há necessidade de usar funções de baixo nível por enquanto na sua aplicação. Em um dos meus posts anteriores tem um link sobre o padrão de projeto Produtor/Consumidor e a imagem dele. Esta imagem você pode arrastar para o seu diagrama de blocos que ela se tornará um código e você poderá testá-lo.

 

Seguindo suas orientações, vou alocar a aquisição de imagem em um (while) loop. O restante (log, calculo, display e gráfico) ficariam em outro(s) loops. Mas como conseguirei o processamento paralelo dos loops? E qual a melhor forma de ajustar a velocidade para o log, calculo, display e gráfico nos valores que desejo?

 

Vamos fazer o seguinte. Para eu não ter que falar muita coisa de cada vez e você não ficar confuso, faça somente isso primeiro (separe em dois loops usando o parão de projeto Produtor/Consumidor). Depois me mande o código para eu ver e sugerir outras mudanças (vá salvando versões do seu código para caso eu não consiga responder por um tempo, você tenha um código funcional com você)

 

Aguardo seu VI.

 

Atenciosamente.

Felipe Flores
Technical Support Engineer
National Instruments
0 Kudos
Mensagem 4 de 10
41.632Exibições

Olá Felipe

 

Desculpe-me pela demora. Segue abaixo algumas respostas ao seu questionamento e os anexos.

 

P: Do log tudo bem, mas você precisa realmente que o gráfico e o display tenham temporizações diferentes? Por quê?
R: Para o gráfico e log preciso de uma leitura mais rápida para perceber a passagem de trincas na chapa (10ms ou menos) (chapa a 250m/min = 0,042m/10ms).
No display preciso de uma leitura média ao longo da chapa (1s) somente para o operador perceber desvios na ordem de 1mm.

 

P: Seu log precisa gravar só um valor (O mais recente) a cada 5 min. ou você precisa gravar todos os resultados?
R: preciso de todos os resultados; para a monitoração da passagem de trincas, o log será a fonte de consulta posterior para confirmar o defeito.

 

Obs.: quanto ao vi em anexo, está programado para iniciar automaticamente. Necessário selecionar imagem no diretorio (na aplicação para campo, ao inves de selecionar imagem, tem se a mesma em tempo real vindo da camera; fiz essa modificação somente para testar offline).

 

Obrigado,

 

Alexandre.

Baixar tudo
0 Kudos
Mensagem 5 de 10
35.103Exibições

Olá Felipe

 

Esqueci de mencionar que após modificar a vi, colocando a parte de aquisição e tratamento de imagem em um loop isolado do restante do programa, não foi mais detectado travamento ou lentidão na execução do vi.

 

Atenciosamente,

 

Alexandre.

0 Kudos
Mensagem 6 de 10
35.102Exibições

Olá Felipe

 

Segue as Vis atualizadas utilizando as queues.

Na v02 utilizei em um dos loops a temporazição de software mas a execução ficou lenta. Na v03 temporizei os loops em execução e rodou normalmente.

Não consegui visualizar o porque dessa diferença.

 

Alexandre.

Baixar tudo
0 Kudos
Mensagem 7 de 10
35.073Exibições

Olá Alexandre,

 

Gostaria de te dar os parabéns. Seu código está muito melhor!! Smiley feliz

 

Vamos trabalhar com a versão v02 está melhor, ok!?

 

Bom,  uma coisa que eu notei com a sua aplicação é a quesão do Log: Você vai querer adiquirir e mostrar dados a casa 10ms pro gráfico e a cada 1 segundo para o display digital. Quando pasar o tempo contado pela função Elapsed Time ( que é de 5 segundos) todos os dados acumulados durante aquele periodo devem ser "despejados" para o arquivo de log. Usando a função Dequeue Element ele vai tirando ponto a ponto , o que deixa a gravação muito mais lenta e, como você colocou o indicador gráfico junto com a função Write to Measurement File, o gráfico também ficará lento por consequencia.

 

O Ideal neste case é que você use a função Flush Queue para jogar todos os dados acumulados na fila para o arquivo de log de uma vez. Outra coisa é tirar o gráfico do loop de log e colocá-lo junto com display digital no loop de apresentação de dados para o usuário.

 

Outro ponto: Não é correto trabalhar com a função Dequeue element em mais de um loop consumidor. Pense que uma fila é um único espaço de memória compartilhado por todo o código. Se você usa a função dequeue para retirar um dado da fila em um loop, o outro loop não poderá pegar este dado, uma vez que ele já foi retirado da fila.

 

Sendo assim, para poder manter os dados na fila e ao mesmo tempo mostrar no gráfico e no display, você pode usar uma função Preview Queue Element para ver o elemento mais recente colocado na fila. Como ela sempre olha para o elemento que está mais a frente na fila, é necessário enfileirar os dados sempre na frente, então use a função Enqueue Element At Opposite End.

 

O uso de filas para enviar o comando de parada não funciona muito bem na estrutura de código que você montou. Use variáveis locais. Elas vão te servir muito bem.

 

Eu fiz algumas das modificações que comentei neste post. Dê uma olhada e implemente o que falta.

 

Atenciosamente.

Felipe Flores
Technical Support Engineer
National Instruments
0 Kudos
Mensagem 8 de 10
35.031Exibições

Olá Felipe

 

O código realmente ficou mais organizado e funcionando sem travamento.

Não ficou muito claro como usar o Enqueue Element At Opposite End. Seria uma opção no lugar do Preview Queue Element ou os dois funcionam em conjunto?

Também gostaria de saber se há como duplicar uma variavel local. No meu caso tive que criar outra em paralelo para fazer o stop em dois loops.

Segue o código corrigido conforme sua orientação.

 

Obrigado,

Alexandre.

0 Kudos
Mensagem 9 de 10
35.017Exibições

Olá Alexandre,


O código realmente ficou mais organizado e funcionando sem travamento.

Perfeito! É legal de ver que, mesmo levando um tempo maior pra ser feito, você está fazendo usando as estruturas certas e vendo que o LabVIEW pode ser muito poderoso, desde que saibamos como usá-lo corretamente. Smiley feliz

Não ficou muito claro como usar o Enqueue Element At Opposite End. Seria uma opção no lugar do Preview Queue Element ou os dois funcionam em conjunto?

 Então, eu vi aqui e acho que a melhor opção na verdade é deixar como está (usando a Enqueue Element) e em vez de usar a Preview Queue Elements, use uma vairável local. Vai ficar assim:

 

Loop gráfico e indicador digital.png

 


Também gostaria de saber se há como duplicar uma variavel local. No meu caso tive que criar outra em paralelo para fazer o stop em dois loops.

    Com certeza você pode! Só copiar e colar a vairável Local. No código modificado eu coloquei duas cópias da variável local Stop no código para você!.

 

Faça as modificações e me apresente os resultados.

 


Atenciosamente.

Felipe Flores
Technical Support Engineer
National Instruments
0 Kudos
Mensagem 10 de 10
35.003Exibições