Страница 1 из 3

Наилучший способ передачи множества параметров в SubVI

Добавлено: 15 янв 2016, 23:02
dadreamer
Собственно, давно уже интересует наиболее оптимальный способ передать в подприбор кучу входных параметров. Знаю, что можно придумать массу вариантов. Но мне хотелось бы, чтобы это выглядело компактно на БД и в то же время позволяло загнать в SubVI стопицот параметров. До последнего использовал кластеры, но меня уже утомила их громоздкость в плане сборки/разборки:
2016-01-16_0-32-41.jpg
2016-01-16_0-32-41.jpg (75.63 КБ) 12653 просмотра
В этом маленьком примере сами индикаторы + Bundle занимают места больше раз в 10, чем сам SubVI. Когда в проекте очень много SubVI и контролов/индикаторов, диаграмма превращается в ад! А хотелось бы всё-таки достичь идеала - чтобы БД верхнего уровня помещалась на экран монитора.

Пробовал вообще не передавать в ВПП параметры, а внутри подприбора рекурсивно обойти панель основного VI и извлечь нужные контролы/индикаторы:
Snippet.png
При небольшом числе элементов на ЛП это работает в принципе нормально. Когда элементов уже много, перебор начинает занимать приличное время (доходило до сотен миллисекунд), что сказывается на общем времени работы алгоритма SubVI. Очевидно, что Property/Invoke Nodes задействуют UI поток, потому такой способ не подходит.

Из того, что на ум приходило:
- при инициализации создать кластер/массив во всеми элементами (ссылками) и в SubVI уже отправлять этот кластер;
- создать какое-то хранилище элементов типа уведомителя или DVR, к которому можно обращаться в каждом SubVI;

Но тут уже возникают задачи поиска нужного элемента в кластере/массиве (по первому подходу) или обновления хранилища (по второму подходу).
Не хотелось бы изобретать велосипед лишний раз. Вопрос, вроде как, лежит на поверхности.

В этом плане у текстовых языков программирования есть преимущество: в любой процедуре/функции можно обратиться к любому элементу формы как-то так: Form1.Edit1.Text

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 15 янв 2016, 23:42
IvanLis
dadreamer писал(а):Не хотелось бы изобретать велосипед лишний раз. Вопрос, вроде как, лежит на поверхности.
На мой взгляд, нужно продумывать структуру программы и организацию вложенности SubVI, что бы не было необходимости ломать над этим голову, т.е. придерживаться структурно-функционального подхода в программировании.

Правда тут нужно "отделить зерна от плевел".
Тема сформулирована:
Наилучший способ передачи множества параметров в SubVI
Но судя из рассуждений, вопрос больше касается работы с лицевой панелью:
В этом плане у текстовых языков программирования есть преимущество: в любой процедуре/функции можно обратиться к любому элементу формы как-то так: Form1.Edit1.Text
Что касается передачи "кучи" переменных в SubVI. Это аналог функции (процедуры) в текстовых языках программирования, раз уж о них заговорили. Я много всего перепробовал, но не встречал функций, которые бы принимали больше 10-15 параметров. Это парадигма структурного программирования.

Что касается обращения к лицевой панели VI более высокого уровня из SubVI, на мой взгляд это крайне неверно и противоречит парадигме функционального программирования, да и вообще понятию "функция" (по крайней мере, как я себе представляю):
- Повышение надёжности
- Модульное тестирование
- Оптимизация
- Параллелизм

Да и сложно себе представить лицевую панель программы, которая содержит несколько сотен различных элементов (контрол/индикатор), но это уже больше вопросы эргономики.

---------------------
Конечно и в моей практике были большие программы, в которых приходилось гонять много данных, я поступал следующим образом. Создавал кластер (TypeDef), в него скидывал все "общие" переменные. Потом гнал этот кластер от функции к функции. В каждой функции выделялись необходимые переменные и считывались, а после перезаписывались на новые. Получается, что на входе и выходе всех функций один и тот же кластер, только значения изменяются.

А что касается подхода: одна VI - один экран. Это далеко не панацея, да и экраны у всех разные :wink: .

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 16 янв 2016, 01:23
Borjomy_1
Когда в проекте очень много SubVI и контролов/индикаторов, диаграмма превращается в ад!
Надо сокращать количество контролов и индикаторов...

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 16 янв 2016, 15:22
dadreamer
IvanLis писал(а):Но судя из рассуждений, вопрос больше касается работы с лицевой панелью:
Вопрос, скорее, на стыке двух областей. Просто способ чтения контролов/индикаторов напрямую с панели - это как один из вариантов получить недостающие параметры внутри SubVI. То есть, если бы эти параметры были введены в SubVI, то не было бы нужды читать панель.
IvanLis писал(а):Я много всего перепробовал, но не встречал функций, которые бы принимали больше 10-15 параметров.
Ну, обычно, не требуется передавать в функцию более 15 параметров. Но возможность такая есть: например, в С функция sprintf может принять бесчисленное множество параметров:

Код: Выделить всё

int sprintf ( char * str, const char * format, ... );
И, как я уже писал, в процедурах и функциях текстовых языков есть возможность чтения данных с формы, потому можно передать в функцию несколько основных параметров и не париться.
IvanLis писал(а):Что касается обращения к лицевой панели VI более высокого уровня из SubVI, на мой взгляд это крайне неверно и противоречит парадигме функционального программирования, да и вообще понятию "функция" (по крайней мере, как я себе представляю):
- Повышение надёжности
- Модульное тестирование
- Оптимизация
- Параллелизм
Ну, я не думаю, что чтение панели из подпрограммы нарушает хоть один из этих пунктов. Я ничего не говорил о записи из SubVI, и не рассматриваю этот момент. Это примерно то же, что в основном VI записать параметры в файл, а в SubVI прочитать их из файла. Но я с этим не стал связываться, т.к. оказывается вовлечён фактор работы с файловой системой, что вносит лишнюю задержку времени выполнения кода. Да и, на самом деле, я также отказался и от чтения панели в SubVI, т.к. это тоже довольно инерционный подход. Потому, следует поискать иные варианты.
IvanLis писал(а):Да и сложно себе представить лицевую панель программы, которая содержит несколько сотен различных элементов (контрол/индикатор), но это уже больше вопросы эргономики.
Несколько - вряд ли. Но сотня порой набирается. Обычно всё это дело разнесено по вкладкам Tab Control'а и не мешает друг другу. На ЛП всё компактно и органично, хотелось бы и на БД сделать так же.
Конечно и в моей практике были большие программы, в которых приходилось гонять много данных, я поступал следующим образом. Создавал кластер (TypeDef), в него скидывал все "общие" переменные. Потом гнал этот кластер от функции к функции. В каждой функции выделялись необходимые переменные и считывались, а после перезаписывались на новые. Получается, что на входе и выходе всех функций один и тот же кластер, только значения изменяются.
Вариант 1 из моего первого сообщения. В кластере были только контролы или так же и индикаторы? Положим, контролы при передаче в SubVI всегда имеют актуальное значение, потому можно хоть сам кластер завести, хоть его локальную переменную. А где обновлять индикаторы? После каждого вызова SubVI? Ещё такой момент: при группировке всех элементов в кластер на ЛП они оказываются заключены в рамку этого кластера. То есть, по вкладкам Tab Control'а уже не разнести. Не совсем удобно.
А что касается подхода: одна VI - один экран. Это далеко не панацея, да и экраны у всех разные :wink: .
Ну да, я сам так считаю, даже вёл дискуссии на эту тему. Кстати, интересный момент: если открыть древние VI (взять те же NI'шные инструменты из старых LV), то их диаграммы часто выглядят как небольшой квадрат с мешаниной из графики. Раньше мониторы были маленького размера, а программисты всё равно старались следовать тому, чтобы диаграмма помещалась на экран.
Но всё-таки хотелось бы компактности и простоты построения кода. Что до сих пор недолюбливаю в LabVIEW, так это лапшу из проводов, и кашу из контролов/индикаторов, VI и структур. Порой на приведение к красивому виду времени уходит больше, чем на кодинг. В этом плане, опять же, текстовый код проще сделать красивым.
Borjomy_1 писал(а):Надо сокращать количество контролов и индикаторов...
Не всегда это получается. В релизе конечно индикаторов и контролов по минимуму. В отладочных версиях полно отладочных контролов/индикаторов, которые нужны для проверки разных алгоритмов и т.п. Кроме того, порой приходится переделывать чужие программы и тут уж никуда не деться. Удалить лишние контролы/индикаторы я не могу, потому что они уже нужны и описаны. Остаётся только загонять их все в подпрограмму.

Когда-то видел интересный подход с очередью из параметров. По-моему, там нужно было помещать параметры в очередь, удалять из неё и модифицировать отдельными :vi: . Правда, не помню, в чём заключался сам принцип такого механизма.

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 16 янв 2016, 21:53
Artem.spb
А чем собственно "первый" пример не устраивает? тем, что сбор в кластер занимает много места?
Я тоже пользуюсь методом, описанным Иваном: в начале собираю все необходимые параметры в кластер, а дальше гоняю этот кластер сквозь :vi: , даже если внутри нужны не все параметры. Это гораздо проще и элегантнее, чем собирать перед каждым subVI нужный ему кластер и отправлять внутрь только "полезную" информацию.

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 17 янв 2016, 00:14
IvanLis
dadreamer писал(а):Вариант 1 из моего первого сообщения. В кластере были только контролы или так же и индикаторы? Положим, контролы при передаче в SubVI всегда имеют актуальное значение, потому можно хоть сам кластер завести, хоть его локальную переменную. А где обновлять индикаторы? После каждого вызова SubVI? Ещё такой момент: при группировке всех элементов в кластер на ЛП они оказываются заключены в рамку этого кластера. То есть, по вкладкам Tab Control'а уже не разнести. Не совсем удобно.
В принципе Artem.spb уже дал ответ.

В кластере не контролы/индикаторы (разницы в них практически нет, их значение всегда доступно через свойства), а именно значение. Я также в кластер часто закидываю пути к файлам, ссылки, параметры и свойства, короче все что нужно в процессе работы.

В процессе работы, при переходе от функции к функции, необходимые данные из кластера считываются, которые нужно - обновляем и т.д. и т.п.

Что касается их отображения, то делается это по событию или после окончания итерации, при этом из кластера вытаскиваются необходимые значения и закидываются в соответствующие индикаторы. При необходимости можно это делать после каждой функции, хотя смысла в этом не вижу.
Получается, что значения всех индикаторов обновляются разом, для ускорения можно заблокировать FP, что бы она перерисовывалась только после полного обновления.

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 17 янв 2016, 13:37
dadreamer
В итоге останавливаюсь пока что на каком-то из этих решений:
1) кластер из ссылок на контролы и индикаторы;
2) кластер из значений контролов и индикаторов;
3) смесь 1 и 2.
Наверное, всё-таки 1 удобнее, чем 2 или 3. По ссылке всегда можно получить актуальное значение контрола/индикатора где угодно, и не только. Можно получить любые свойства этого элемента. И при необходимости обновить элемент. Для решения 2 нужно отдельно "синхронизировать" текущие значения индикаторов/контролов со значениями в кластере. Как до подачи в ВПП, так и после.

В общем, как буду делать новый проект, попробую. Также, может, посмотрю какие-то другие решения, если не устроят эти.

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 17 янв 2016, 16:00
Artem.spb
dadreamer писал(а):В итоге останавливаюсь пока что на каком-то из этих решений:
1) кластер из ссылок на контролы и индикаторы;
2) кластер из значений контролов и индикаторов;
3) смесь 1 и 2.
.
я как раз использую 1+2, но это два разных кластера:
1) кластер ссылок для управления FP (заблокировать, переключить tab и т.п. в том числе можно и обновить значение)
2) кластер рабочих параметров, необходимых для расчётов, но не нежных пользователю (те самые пути к файлам)

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 19 янв 2016, 11:07
ESeid
dadreamer писал(а):В итоге останавливаюсь пока что на каком-то из этих решений:
1) кластер из ссылок на контролы и индикаторы;
2) кластер из значений контролов и индикаторов;
3) смесь 1 и 2.
Наверное, всё-таки 1 удобнее, чем 2 или 3. По ссылке всегда можно получить актуальное значение контрола/индикатора где угодно, и не только. Можно получить любые свойства этого элемента. И при необходимости обновить элемент. Для решения 2 нужно отдельно "синхронизировать" текущие значения индикаторов/контролов со значениями в кластере. Как до подачи в ВПП, так и после.

В общем, как буду делать новый проект, попробую. Также, может, посмотрю какие-то другие решения, если не устроят эти.
Очень интересный подход. У меня в готовых инструментах до 30-40 индикаторов+контролов, я их группировал в кластеры, но вот до кластера ВСЕХ ссылок не додумался. Спасибо за идею, буду пробовать.

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 19 янв 2016, 12:57
Pavel
Кластер чем неудобен, так это тем что при передачи в субвиай делается его копия. В принципе для референсов это будет не критично, но если передавать весь кластер со всеми данными (допустим супер кластер) то при большом проекте копирование кластера будет отъедать место.

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 19 янв 2016, 22:54
Artem.spb
Pavel писал(а):Кластер чем неудобен, так это тем что при передачи в субвиай делается его копия. В принципе для референсов это будет не критично, но если передавать весь кластер со всеми данными (допустим супер кластер) то при большом проекте копирование кластера будет отъедать место.
ну это не совсем так, точнее, зависит от того, как передавать
mem.png
на верхней строке кластер передаётся в функцию, там обрабатывается и отправляется наружу. копии не создаются.
В нижней строке при отправке в каждую функцию создаётся копия.
Но идея в частности в том чтобы кластер передавался от функции к функции (и через сдвиговый регистр в цикле), чтобы в нём всегда была актуальная информация (например для скользящего среднего надо хранить некоторую историю). И в этом случае копий не создаётся.

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 20 янв 2016, 09:08
Pavel
Если речь идет о сабвиай, то при вызове делается копия всех параметров (так было до LV 2010, уже давно не пишу программы но думаю ничего не поменялось). В Labview есть/был инструмент Show Buffer Allocations, посмотрите им.

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 20 янв 2016, 10:17
Artem.spb
Pavel писал(а):Если речь идет о сабвиай, то при вызове делается копия всех параметров (так было до LV 2010, уже давно не пишу программы но думаю ничего не поменялось). В Labview есть/был инструмент Show Buffer Allocations, посмотрите им.
Не знаю, откуда ы Вас такая странная информация. Вы бы сами проверили, прежде чем путать людей.
Вот скрин моего текущего проекта. Чёрные точки - выделение памяти. И так было с тех пор, когда я первый раз проверил это дело. ещё в 8 или 2009
mem.png

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 20 янв 2016, 13:15
Pavel
У вас красным "овалом" обведено выделение памяти под кластера, то же самое происходит и в сабвиай. Т.е. при вызове подпрограммы LV выделит память и скопирует туда кластер.

Re: Наилучший способ передачи множества параметров в SubVI

Добавлено: 20 янв 2016, 15:28
Artem.spb
Pavel писал(а):У вас красным "овалом" обведено выделение памяти под кластера, то же самое происходит и в сабвиай. Т.е. при вызове подпрограммы LV выделит память и скопирует туда кластер.
это утверждение даже звучит нелогично.
что же в таком случае происходит с оригинальными данными?