Советы по программированию на LabVIEW
-
- doctor
- Сообщения: 2244
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 30 раз
- Поблагодарили: 30 раз
Re: Советы по программированию на LabVIEW
Рекомендовал бы избавиться от двухмерного результирующего массива, заменить его одномерным. И скдадывать в сдвиговый регистр.
Убрать обмен байтами из приема.
После приёма полного фрейма последующую обработку проводить в отдельном цикле, куда передавать принятый буфер. Там уже делать и обмен байтами и перевод в двухмерный массив.
Проблема с двухмерными массивами в том, что скорость заполнения по строкам и столбцам разная.
Убрать обмен байтами из приема.
После приёма полного фрейма последующую обработку проводить в отдельном цикле, куда передавать принятый буфер. Там уже делать и обмен байтами и перевод в двухмерный массив.
Проблема с двухмерными массивами в том, что скорость заполнения по строкам и столбцам разная.
- nae
- user
- Сообщения: 79
- Зарегистрирован: 20 мар 2014, 14:21
- Версия LabVIEW: 15
- Откуда: Новосибирск
- Благодарил (а): 5 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
Поиск совсем не лимитирует производительность.
Переворачивать и объединять "потом" - не получается - нужно искать по слову (из двух байт), а как это экономично сделать без перепаковки страницы из U8 в U16 - я пока не понял.
Продолжаю копать...
Похоже я много времени провожу в функциях FTDI READ в ожидании данных. Т.е. я прошу следующую страницу, а чип ещё не закончил её передачу и CLFN ждёт пока библиотека получит требуемое количество и отдаст управление.
Можно ли с помощью функции Wait или wait untill скажем с дискретой в 1..5мс отдавать управление другим процессам? Скажем спросить есть ли в буфере нужное количество, если пока нет, подождать 1мс (отдав управление куда-то), потом снова спросить?
UPD:
Вроде передача управления по Wait работает.
Сейчас на том же стареньком ноуте при 25фпс вообще нет проблем - успеваю даже перевести показания в температуру через полином третей степени и нарисовать в Intecity chart (в отдельном timed loop).
А на 50ФПС пока что успеваю только читать в кадровый буфер U16 с загрузкой 5% по данным винды. А вот с температурой и визуализацией опять идёт упор в ядро, но при этом общая загрузка не поднимается выше 50% - есть куда копать...
Переворачивать и объединять "потом" - не получается - нужно искать по слову (из двух байт), а как это экономично сделать без перепаковки страницы из U8 в U16 - я пока не понял.
Продолжаю копать...
Похоже я много времени провожу в функциях FTDI READ в ожидании данных. Т.е. я прошу следующую страницу, а чип ещё не закончил её передачу и CLFN ждёт пока библиотека получит требуемое количество и отдаст управление.
Можно ли с помощью функции Wait или wait untill скажем с дискретой в 1..5мс отдавать управление другим процессам? Скажем спросить есть ли в буфере нужное количество, если пока нет, подождать 1мс (отдав управление куда-то), потом снова спросить?
UPD:
Вроде передача управления по Wait работает.
Сейчас на том же стареньком ноуте при 25фпс вообще нет проблем - успеваю даже перевести показания в температуру через полином третей степени и нарисовать в Intecity chart (в отдельном timed loop).
А на 50ФПС пока что успеваю только читать в кадровый буфер U16 с загрузкой 5% по данным винды. А вот с температурой и визуализацией опять идёт упор в ядро, но при этом общая загрузка не поднимается выше 50% - есть куда копать...
-
IvanLis
- guru
- Сообщения: 5524
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 32 раза
- Поблагодарили: 98 раз
Re: Советы по программированию на LabVIEW
Вам нужно раскидать задачи по нескольким процессам (циклам).
Первый цикл (квази реального времени) занимается только общением с железкой, получив пакет данных отправляет (очередь - queue) его во второй цикл и снова становится в ожидание.
Второй цикл (асинхронно работает с первым), принимает от первого данные и выполняет их обработку.
На этом можно остановиться.
Но я бы рекомендовал все процессы работы с UI вынести в третий цикл, который получает данные от второго цикла через уведомления (notifier) и занимается только отображением информации. Причем если он не успевает за первыми двумя, то отображает последние - актуальные данные.
Важно! первые два цикла не должны иметь никаких связей с UI, в том числе и Reference. Если нужны какие-то данные, типа как у Вас FTDI-Handle, то все данные из UI считываем за пределами цикла.
---------------
p.s. Иногда специально раскидываю по разным циклам одну задачу, если необходимо обеспечить требуемое быстродействие.
Такой прием и в FPGA используется - типа псевдо распараллеливание, но там через сдвиговые регистры гоняют данные между итерациями.
Первый цикл (квази реального времени) занимается только общением с железкой, получив пакет данных отправляет (очередь - queue) его во второй цикл и снова становится в ожидание.
Второй цикл (асинхронно работает с первым), принимает от первого данные и выполняет их обработку.
На этом можно остановиться.
Но я бы рекомендовал все процессы работы с UI вынести в третий цикл, который получает данные от второго цикла через уведомления (notifier) и занимается только отображением информации. Причем если он не успевает за первыми двумя, то отображает последние - актуальные данные.
Важно! первые два цикла не должны иметь никаких связей с UI, в том числе и Reference. Если нужны какие-то данные, типа как у Вас FTDI-Handle, то все данные из UI считываем за пределами цикла.
---------------
p.s. Иногда специально раскидываю по разным циклам одну задачу, если необходимо обеспечить требуемое быстродействие.
Такой прием и в FPGA используется - типа псевдо распараллеливание, но там через сдвиговые регистры гоняют данные между итерациями.
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
- nae
- user
- Сообщения: 79
- Зарегистрирован: 20 мар 2014, 14:21
- Версия LabVIEW: 15
- Откуда: Новосибирск
- Благодарил (а): 5 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
Залетали бы у меня эти данные в sb9637 - я бы не раздумывая спихнул всё в плис - истинный параллелизм во всей красе - если проект синтезировался, то кривизна кода там уже не так страшна :) (гуев снизу нет - нет простора для рукожопства)IvanLis писал(а): ↑11 июл 2022, 17:15 Вам нужно раскидать задачи по нескольким процессам (циклам).
Первый цикл (квази реального времени) занимается только общением с железкой, получив пакет данных отправляет (очередь - queue) его во второй цикл и снова становится в ожидание.
Второй цикл (асинхронно работает с первым), принимает от первого данные и выполняет их обработку.
На этом можно остановиться.
Но я бы рекомендовал все процессы работы с UI вынести в третий цикл, который получает данные от второго цикла через уведомления (notifier) и занимается только отображением информации. Причем если он не успевает за первыми двумя, то отображает последние - актуальные данные.
Важно! первые два цикла не должны иметь никаких связей с UI, в том числе и Reference. Если нужны какие-то данные, типа как у Вас FTDI-Handle, то все данные из UI считываем за пределами цикла.
---------------
p.s. Иногда специально раскидываю по разным циклам одну задачу, если необходимо обеспечить требуемое быстродействие.
Такой прием и в FPGA используется - типа псевдо распараллеливание, но там через сдвиговые регистры гоняют данные между итерациями.
Минивопрос:
Очереди - это файфо, нотифаеры - это прерывания, а кто такие семафоры и рандеву и окьюренсы(на языке... МК или FPGA)???
- nae
- user
- Сообщения: 79
- Зарегистрирован: 20 мар 2014, 14:21
- Версия LabVIEW: 15
- Откуда: Новосибирск
- Благодарил (а): 5 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
Подскажите пожалуйста правильно ли я применил очереди и нотифаеры? (я использую их впервые...) Индикатор заполнения очереди показывает, что она пуста, т.е. элементы в ней не скапливаются.
Картинка от 50фпс бегает (но видно, что примерно каждый третий кадр не успевает). Нагрузка процесса возросла до 40% а общая нагрузка по монитору примерно вдвое выше.
На 25фпс пропусков нет, попоытки подергать окошки не приводят к потере кадров.
Нужно ли отслеживать то, что очередь пуста/нотифаер не установлен и не выполнять операции в этом случае или это само происходит? В том смысле, что установить нулевой таймаут и если пусто, то ни чего не делать и перейти к wait.
Нужно ли заменить это timed loop ы чтобы что-то улучшить?
UPD: Вставил нулевые таймауты в выборки, настроил приоритеты таймедлупов, вроде особо ни чего не изменилось. Статистика показывает, что ошибок в вычитке кадров нет даже на 50Гц, но на отрисовке по нотифаеру счетчик кадров показывает, что он через один пропускает кадры. Пока он рисует новый нотифаер успевает затереть предыдущий ещё не отрисованый.
UPD2: А если закрыть браузер, монитор активности и вообще всё что можно выключить и не шуметь в комнате, то времени начинает хватать! Вываливается из отрисовки всего примерно один кадр за 20 секунд. Наверное это уже хороший результат, по крайней мере не очень уступающий похожей программе коллеги на дельфи...
Картинка от 50фпс бегает (но видно, что примерно каждый третий кадр не успевает). Нагрузка процесса возросла до 40% а общая нагрузка по монитору примерно вдвое выше.
На 25фпс пропусков нет, попоытки подергать окошки не приводят к потере кадров.
Нужно ли отслеживать то, что очередь пуста/нотифаер не установлен и не выполнять операции в этом случае или это само происходит? В том смысле, что установить нулевой таймаут и если пусто, то ни чего не делать и перейти к wait.
Нужно ли заменить это timed loop ы чтобы что-то улучшить?
UPD: Вставил нулевые таймауты в выборки, настроил приоритеты таймедлупов, вроде особо ни чего не изменилось. Статистика показывает, что ошибок в вычитке кадров нет даже на 50Гц, но на отрисовке по нотифаеру счетчик кадров показывает, что он через один пропускает кадры. Пока он рисует новый нотифаер успевает затереть предыдущий ещё не отрисованый.
UPD2: А если закрыть браузер, монитор активности и вообще всё что можно выключить и не шуметь в комнате, то времени начинает хватать! Вываливается из отрисовки всего примерно один кадр за 20 секунд. Наверное это уже хороший результат, по крайней мере не очень уступающий похожей программе коллеги на дельфи...
-
IvanLis
- guru
- Сообщения: 5524
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 32 раза
- Поблагодарили: 98 раз
Re: Советы по программированию на LabVIEW
1. в цикле Collect loop: Чтение из локальной переменной (stop loop), убирайте локалку и оставляйте только остановку по ошибке.
2. в цикле Process Data loop: stop loop - аналогично 1. timeout queue = -1 (в холостую не крутим, так время реакции на реальные данные повышаем). И убираем все обращения к GUI (Вы продолжаете писать в TimeConsum.... и дергать локалки), в том числе локалки. Локальная переменная не так тормозит как Ref, но тоже тормозит. Вот наглядный пример. по этому, все операции с GUI переносим в цикл Plot loop.
Если нужно что-то отображать, то шлите туда и там отображайте.
А в рабочих циклах все храним в сдвиговых регистрах и считаем там же.
3. Длину очереди ограничивать не стоит, иначе можно потерять данные. Ну и контролировать особо смысла нет, разве что на этапе отладки.
4. Кнопку stop loop кидаем в цикл Plot loop, а по ее нажатии и выхода из цикла, уничтожаем Queue и Notifier, что вызовет ошибку в остальных циклах и они остановятся.
И нужны ли Вам RT циклы? Разве только для Collect loop, остальные точно не нужны, они по поступлении данных должны работать, а не по времени.
И почему Вы в Intensity Graph через указатель пишите данные, если можно напрямую пихать, сразу в контрол?
Может еще что есть, но постарался все учесть....
2. в цикле Process Data loop: stop loop - аналогично 1. timeout queue = -1 (в холостую не крутим, так время реакции на реальные данные повышаем). И убираем все обращения к GUI (Вы продолжаете писать в TimeConsum.... и дергать локалки), в том числе локалки. Локальная переменная не так тормозит как Ref, но тоже тормозит. Вот наглядный пример. по этому, все операции с GUI переносим в цикл Plot loop.
Если нужно что-то отображать, то шлите туда и там отображайте.
А в рабочих циклах все храним в сдвиговых регистрах и считаем там же.
3. Длину очереди ограничивать не стоит, иначе можно потерять данные. Ну и контролировать особо смысла нет, разве что на этапе отладки.
4. Кнопку stop loop кидаем в цикл Plot loop, а по ее нажатии и выхода из цикла, уничтожаем Queue и Notifier, что вызовет ошибку в остальных циклах и они остановятся.
И нужны ли Вам RT циклы? Разве только для Collect loop, остальные точно не нужны, они по поступлении данных должны работать, а не по времени.
И почему Вы в Intensity Graph через указатель пишите данные, если можно напрямую пихать, сразу в контрол?
Может еще что есть, но постарался все учесть....
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
- nae
- user
- Сообщения: 79
- Зарегистрирован: 20 мар 2014, 14:21
- Версия LabVIEW: 15
- Откуда: Новосибирск
- Благодарил (а): 5 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
Intencity graph в отдельном VI размещен - вот и пишу по указателю )
Запись в локальный intencity chart не меняет загрузку потока, но улучшает синхронизацию - не получилось увидеть пропуск отрисовки перемещением окна.
-
- adviser
- Сообщения: 239
- Зарегистрирован: 06 ноя 2020, 15:37
- Версия LabVIEW: 19
- Благодарил (а): 19 раз
- Поблагодарили: 38 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
Цикл Plot loop так же зависит от данных из цикла Process Data loop, следовательно timeout notifier так же лучше сделать -1
Цикл Plot loop и Process Data loop имеют одинаковый период 1 мс. Следовательно при выполнении цикла Plot loop больше чем 1 мс он пропускает данные.
Чтобы не пропускал, этот цикл можно заменить на while loop и не ставить задержки по времени в цикле.
Согласен, только добавлю небольшое пояснение. RT циклы предназначены для RT систем (NILinuxRT и др). Хоть в Windows приоритеты выполняются и разбивка по процессорам выполняется,
однако время цикла все равно плавает в широких пределах. Без пропусков в последнем цикле не получится. В данном случае RT циклы не помогут.
И в обычных while loop время цикла так же будет плавать в широких пределах, так как LabVIEW для Windows не самая приоритетная задача.
- nae
- user
- Сообщения: 79
- Зарегистрирован: 20 мар 2014, 14:21
- Версия LabVIEW: 15
- Откуда: Новосибирск
- Благодарил (а): 5 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
Подчистил лишнее. Выглядит как-то слишком просто и компактно в сравнении с тем с чего начинал... Работает отлично.
-
IvanLis
- guru
- Сообщения: 5524
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 32 раза
- Поблагодарили: 98 раз
Re: Советы по программированию на LabVIEW
Можно указатель Queue не тянуть через верхний цикл, а очередность уничтожения задать "проводом" ошибки. Ну а что касается простоты, так это наоборот хорошо
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
- nae
- user
- Сообщения: 79
- Зарегистрирован: 20 мар 2014, 14:21
- Версия LabVIEW: 15
- Откуда: Новосибирск
- Благодарил (а): 5 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
Очередной чайниковопрос. Имеем USB3 камеру E3CMOS02300KMC. 120fps fullhd.
Нашел какие-то дрова от похожей камеры toup и там даже есть какая-то папка с dll для labview!
внутри две dll для х86 и х64 и h файл со странным содержимым
"
#ifndef __toupcam_labview_h__
#define __toupcam_labview_h__
#include "extcode.h"
#ifdef TOUPCAM_LABVIEW_EXPORTS
#define TOUPCAM_LABVIEW_API(x) __declspec(dllexport) x __cdecl
#else
#define TOUPCAM_LABVIEW_API(x) __declspec(dllimport) x __cdecl
#include "toupcam.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
TOUPCAM_LABVIEW_API(HRESULT) Start(HToupcam h, LVUserEventRef *rwer);
#ifdef __cplusplus
}
#endif
#endif
"
Импортер библиотек labview резонно ругается на это дело, говорит, что в заголовке описаны две функции, а в длл их нет - на этом его полномочия всё.
Может кто-то сталкивался с захватом изображений с usb камер - как это можно сделать через dll? Или нужно обязательно ставить какой-то тулкит?
Нашел какие-то дрова от похожей камеры toup и там даже есть какая-то папка с dll для labview!
внутри две dll для х86 и х64 и h файл со странным содержимым
"
#ifndef __toupcam_labview_h__
#define __toupcam_labview_h__
#include "extcode.h"
#ifdef TOUPCAM_LABVIEW_EXPORTS
#define TOUPCAM_LABVIEW_API(x) __declspec(dllexport) x __cdecl
#else
#define TOUPCAM_LABVIEW_API(x) __declspec(dllimport) x __cdecl
#include "toupcam.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
TOUPCAM_LABVIEW_API(HRESULT) Start(HToupcam h, LVUserEventRef *rwer);
#ifdef __cplusplus
}
#endif
#endif
"
Импортер библиотек labview резонно ругается на это дело, говорит, что в заголовке описаны две функции, а в длл их нет - на этом его полномочия всё.
Может кто-то сталкивался с захватом изображений с usb камер - как это можно сделать через dll? Или нужно обязательно ставить какой-то тулкит?
-
dadreamer
- professor
- Сообщения: 3957
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2024
- Благодарил (а): 12 раз
- Поблагодарили: 138 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
В хэдере явно видна только одна функция - Start (по логике должна быть ещё Stop хотя бы, либо же Start может и стопить, если передать NULL в качестве rwer, например). А из самой DLL какие функции экспортируются? Поглядите через Dependency Walker или TC (Lister). Если DLL специально была разработана для связки с и с этой камерой, то логично именно её использовать. Если камера поддерживает дрова IMAQdx, то можно попытаться увидеть её через MAX и при успехе дальше использовать VDM. Если не поддерживает, то остаются только сторонние библиотеки. Это на вопрос о том, как работать с USB-камерами.
Ещё, общая рекомендация - настраивать CLFN "вручную", не используя мастер импорта, т.к. он часто не может корректно распарсить типы данных и вложенные конструкции.
- nae
- user
- Сообщения: 79
- Зарегистрирован: 20 мар 2014, 14:21
- Версия LabVIEW: 15
- Откуда: Новосибирск
- Благодарил (а): 5 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
Т.е. очевидно, что этот хидер для этих dll не подходит и надо искать какой-то другой...dadreamer писал(а): ↑01 сен 2022, 11:07В хэдере явно видна только одна функция - Start (по логике должна быть ещё Stop хотя бы, либо же Start может и стопить, если передать NULL в качестве rwer, например). А из самой DLL какие функции экспортируются? Поглядите через Dependency Walker или TC (Lister). Если DLL специально была разработана для связки с и с этой камерой, то логично именно её использовать. Если камера поддерживает дрова IMAQdx, то можно попытаться увидеть её через MAX и при успехе дальше использовать VDM. Если не поддерживает, то остаются только сторонние библиотеки. Это на вопрос о том, как работать с USB-камерами.
Ещё, общая рекомендация - настраивать CLFN "вручную", не используя мастер импорта, т.к. он часто не может корректно распарсить типы данных и вложенные конструкции.
-
dadreamer
- professor
- Сообщения: 3957
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2024
- Благодарил (а): 12 раз
- Поблагодарили: 138 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
Нужно внятное описание функций внутри библиотеки. Хэдер по большому счёту и не нужен. Если функций там немного, быстрее будет настроить CLF Nodes, чем обучать встроенный мастер . Судя по тому, что функция Start принимает LVUserEventRef, используется примерно вот такая архитектура: либа принимает данные от API камеры и пересылает в с помощью PostLVUserEvent, в нужно принимать UE (кадры) внутри Event-структуры. Как минимум важно знать тип UE, чтобы разобрать полученные данные.
- nae
- user
- Сообщения: 79
- Зарегистрирован: 20 мар 2014, 14:21
- Версия LabVIEW: 15
- Откуда: Новосибирск
- Благодарил (а): 5 раз
- Контактная информация:
Re: Советы по программированию на LabVIEW
В ридми на диске с дровами написано такоеdadreamer писал(а): ↑01 сен 2022, 13:28Нужно внятное описание функций внутри библиотеки. Хэдер по большому счёту и не нужен. Если функций там немного, быстрее будет настроить CLF Nodes, чем обучать встроенный мастер . Судя по тому, что функция Start принимает LVUserEventRef, используется примерно вот такая архитектура: либа принимает данные от API камеры и пересылает в с помощью PostLVUserEvent, в нужно принимать UE (кадры) внутри Event-структуры. Как минимум важно знать тип UE, чтобы разобрать полученные данные.
"
For Windows Developer
1.Please check files in the SDK directory.
2.MIIDshowSetup.exe is the DirectShow SDK installation file. Running it will install the driver, DirectShow files, sample application and its source code.
3.MIITwainSetup.exe is the TWAIN SDK installation file. Running it will install the driver, TWAIN files, sample application and its source code.
4.nncamsdk.zip is a Native C/C++ SDK for developer, including the demo application and documents for reference.
5.UvcHamSetup.exe is Dshow and Twain for 4K camera and uvchamsdk is SDK for 4K camera.
6.UvcSamSetup.exe is Dshow and Twain for C2CMOS cameras and uvcsamsdk is SDK for C2CMOS cameras.
"
Файлы для LV я нашел в пункте 5. Выбор этой dll в окне настройки CLFN дает посмотреть, что в ней всего две функции: Start и SetLVRTModule. Первая описана в h-файле, а вторая где? (...тяжело узнавать новое...)
Файлы для си выглядят так: можно ли по ним понять структуру данных? Это же для Си?
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение