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

Обсуждение, связанное с разработкой ПО верхнего уровня
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

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

Сообщение dadreamer »

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

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

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

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

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

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

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

Сообщение IvanLis »

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

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

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

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

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

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

Activity Professionalism Silver
doctor
doctor
Сообщения: 2210
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

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

Сообщение Borjomy_1 »

Когда в проекте очень много SubVI и контролов/индикаторов, диаграмма превращается в ад!
Надо сокращать количество контролов и индикаторов...
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

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

Сообщение 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: . Правда, не помню, в чём заключался сам принцип такого механизма.
Artem.spb

Activity Автор
professor
professor
Сообщения: 3391
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

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

Сообщение Artem.spb »

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

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

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

Сообщение IvanLis »

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

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

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

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

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

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

Сообщение dadreamer »

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

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

Activity Автор
professor
professor
Сообщения: 3391
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

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

Сообщение Artem.spb »

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

Автор
advanced
advanced
Сообщения: 150
Зарегистрирован: 30 мар 2011, 22:41
Награды: 1
Версия LabVIEW: 8.2-2013
Контактная информация:

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

Сообщение ESeid »

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

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

Activity
developer
developer
Сообщения: 271
Зарегистрирован: 31 июл 2009, 08:07
Награды: 1
Версия LabVIEW: 8.5

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

Сообщение Pavel »

Кластер чем неудобен, так это тем что при передачи в субвиай делается его копия. В принципе для референсов это будет не критично, но если передавать весь кластер со всеми данными (допустим супер кластер) то при большом проекте копирование кластера будет отъедать место.
Artem.spb

Activity Автор
professor
professor
Сообщения: 3391
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

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

Сообщение Artem.spb »

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

Activity
developer
developer
Сообщения: 271
Зарегистрирован: 31 июл 2009, 08:07
Награды: 1
Версия LabVIEW: 8.5

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

Сообщение Pavel »

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

Activity Автор
professor
professor
Сообщения: 3391
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

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

Сообщение Artem.spb »

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

Activity
developer
developer
Сообщения: 271
Зарегистрирован: 31 июл 2009, 08:07
Награды: 1
Версия LabVIEW: 8.5

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

Сообщение Pavel »

У вас красным "овалом" обведено выделение памяти под кластера, то же самое происходит и в сабвиай. Т.е. при вызове подпрограммы LV выделит память и скопирует туда кластер.
Artem.spb

Activity Автор
professor
professor
Сообщения: 3391
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

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

Сообщение Artem.spb »

Pavel писал(а):У вас красным "овалом" обведено выделение памяти под кластера, то же самое происходит и в сабвиай. Т.е. при вызове подпрограммы LV выделит память и скопирует туда кластер.
это утверждение даже звучит нелогично.
что же в таком случае происходит с оригинальными данными?
Ответить
  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Лицевая панель»