УкраїнськаEnglishmRussian
Вход/Новый
В теме много сообщений

[BugFixed] inf error


Автор Сообщение
Сообщение создано: 29. 11. 2014 [23:59]
pentagon128
Руслан Кучерявый
Создатель темы
Зарегистрирован(а) с: 15.11.2011
Сообщения: 102
При работе с блочным вычислителем столкнулся с тем, что при обработке функции внутри блока значение атрибута параметра (T3 в моём случае) присваивается при первом запуске значение равное inf. Если перезапустить контроллер object001 блочного вычислителя, то функция отрабатывает нормально, T3=54.5 Функция отлажена, вкладка её "Исполнить" при первом запуске выдаёт нормальные значения. Данный тег Т3 является выходом алгоблока T310570, связь ему задана=Свободен. Попытки менять типы связи ни к чему не приводят....

Сборку OpenScada собирал на Raspberry Pi версии где-то 2155-2160 около месяца назад. Видео проблемки прикладываю (разбитый RAR-ом маленький видеофайл в 3 Мб).

[Сообщение редактировалось 1 раз(а), в последний раз 30.11.2014 в 00:06.]
Вложенный файл

inf_Error.part1.rar (Тип файла: application/x-rar-compressed, Размер: 1024 килобайт) — 1206 загрузок
inf_Error.part2.rar (Тип файла: application/x-rar-compressed, Размер: 1024 килобайт) — 1181 загрузок
inf_Error.part3.rar (Тип файла: application/x-rar-compressed, Размер: 150.37 килобайт) — 1204 загрузок
Сообщение создано: 01. 12. 2014 [17:26]
pentagon128
Руслан Кучерявый
Создатель темы
Зарегистрирован(а) с: 15.11.2011
Сообщения: 102
Функции 3 шт. прикрученные к 3-м блокам исполняю в тесте в библиотеке Java вычислителя (вкладка "Исполнить) за 50-150 мс, период исполнения контроллера соответствующих 3-х блоков установлен 5 сек. При первом запуске Openscada в результате вычисления этих 3-х блоков значение=inf. Далее во всех связанных этой переменной блоках тоже inf, т.е. фактически у меня блочный вычислитель не работает (вычисления стоят), при этом он запущен и никаких сообщений о ошибках нет. Могу конечно сделать "костыль" из однократного перезапуска контроллера блочного вычислителя при старте через прописывание кода в JavaCalc шаблона любой задействованной переменной логического уровня, но хочется более изящного решения. Роман, подскажите пожалуйста в каком направлении копать.
Сообщение создано: 01. 12. 2014 [22:22]
roman
Roman Savochenko
Moderator
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
"pentagon128" wrote:

Сборку OpenScada собирал на Raspberry Pi версии где-то 2155-2160 около месяца назад. Видео проблемки прикладываю (разбитый RAR-ом маленький видеофайл в 3 Мб).

И ключевого момента на видео и в описании нет, а именно: алгоритм блока и свойства IO!

Скорее всего сами туда такой мусор и пишите, или вообще ничего не пишете, поскольку:
- На N900 у меня ничего подобного нет.
- На N900 и RaspberyPi запускалась и работала модель АГЛКС, которая целиком реализована в BlockCalc.

Learn, learn and learn better than work, work and work.
Сообщение создано: 02. 12. 2014 [17:15]
pentagon128
Руслан Кучерявый
Создатель темы
Зарегистрирован(а) с: 15.11.2011
Сообщения: 102
Роман -спасибо за подсказку. Проблему удалось локализовать переделкой вызываемой функции. Особенностью этой функции был большой кусок кода выполняемый в рамках стартовой секции 1-го запуска:

if (f_start)//1-й запуск
{
//тело стартовой секции
код стартовой секции
//концовка 1-го запуска
f_start=false;
}

//основное тело функции

в коде стартовой секции объявляются 2 вещественных массива по 60 элементов, далее объявляются ещё 2 массива, которые заполняются на основе вычислений проводимых над первыми двумя массивами. Используется метод т.н. линейной апроксимации. Далее в основном теле функции производятся вычисления над входной переменной используя уже готовые рассчитанные вторичные 2 массива. Т.е. первый запуск функции происходит процентов на 100 медленнее чем последующие, т.к. при последующих вычислениях используются предварительно рассчитанные в стартовой секции массивы. Таким образом экономиться время обработки функции.

При вызове функции в блочном вычислителе время выполнения стартовой секции критично, догадываюсь что срабатывает какой-то таймаут блочного вычислителя и функция в нём не выполняется. Во вкладке - Исполнить же - функция работает нормально. При помещении в блочный вычислитель, выход T3=inf пока не перезапустишь контроллер блочного вычислителя.

Временное решение-убрать стартовую секцию в функции вообще. Тогда блочный вычислитель работает нормально.
Минус данного временного решения - почти двухкратное увеличение времени работы функций (ясен пень - каждый запуск приходиться с нуля опять определять 2 массива и рассчитывать ещё 2 дополнительных), на Raspberry pi с ресурсами не густо.

//if (f_start)//1-й запуск
//{
//тело стартовой секции
код стартовой секции
//концовка 1-го запуска
//f_start=false;
//}

//основное тело функции

ниже привожу полный код функции в варианте со стартовой секцией (не работает при 1-м запуске блочного вычислителя), русский текст к сожалению из Raspberry pi через VNC вытаскивается кракозябрами:
**********************************************
Входа-выхода

1 id=Tnv, имя=Tnv, тип=Веществ, Режим=Вход
2 id=T3, имя=T3, тип=Веществ, Режим=Выход
3 id=f_start, имя=флаг запуска функции, тип=Логич., Режим=Возврат, Умолч=1
**********************************************
Программа

//функция аппроксимирует T3 в зависимости от Tnv

if (f_start)//1-й запуск
{
//Tnv0 60 элементов
var Tnv0 = new Array
(9.00,8.00,7.00,6.00,5.00,4.00,3.00,2.00,1.00,0.00,
-1.00,-2.00,-3.00,-4.00,-5.00,-6.00,-7.00,-8.00,-9.00,-10.00,
-11.00,-12.00,-13.00,-14.00,-15.00,-16.00,-17.00,-18.00,-19.00,-20.00,
-21.00,-22.00,-23.00,-24.00,-25.00,-26.00,-27.00,-28.00,-29.00,-30.00,
-31.00,-32.00,-33.00,-34.00,-35.00,-36.00,-37.00,-38.00,-39.00,-40.00,
-41.00,-42.00,-43.00,-44.00,-45.00,-46.00,-47.00,-48.00,-49.00,-50.00);

//T30 60 элементов
var T30 = new Array
(43.90,43.90,43.70,43.50,43.30,43.10,42.90,42.70,42.60,42.40,
42.90,43.70,44.50,45.30,46.10,46.90,47.70,48.50,49.30,50.00,
51.50,52.30,53.00,53.70,54.50,55.20,55.90,56.60,57.30,58.00,
58.70,59.40,60.10,60.80,61.50,61.80,61.90,62.00,61.70,61.10,
60.50,59.90,59.40,58.80,58.30,61.80,61.90,62.00,61.70,61.10,
60.50,59.90,59.40,58.80,58.30,61.80,61.90,62.00,61.70,61.10);

//рассчитываем a3=(y2-y1)/(x2-x1)
var a3=new Array();
for(var i=0; i < Tnv0.length-1; i++) a3.push((T30[i+1]-T30[i])/(Tnv0[i+1]-Tnv0[i]));
//рассчитываем последний элемент массива
i=Tnv0.length-1;
a3.push(T30[i]/Tnv0[i]);

//рассчитываем b3=y1-x1*a1
var b3=new Array();
for(var i=0; i < Tnv0.length; i++) b3.push(T30[i]-Tnv0[i]*a3[i]);

//концовка 1-го запуска
f_start=false;
}


//рассчитываем j соответствующий входному Tnv
//ограничиваем пределы Tnv
if (Tnv>9.00) Tnv=9.00;
if (Tnv<-50.00) Tnv=-50.00;

var delta=0.00;var deltamin=abs(Tnv-Tnv0[0]);var j=0;
for(var i=0; i < Tnv0.length-1; i++)
{
delta=abs(Tnv-Tnv0[i]);
if (delta<=deltamin)
{deltamin=delta;j=i;}
else
{}
}

//y=ax+b, выход функции
T3=a3[j]*Tnv+b3[j];
********************************************************

ниже код тела функции без стартовой секции
JAVASCRIPT
//функция аппроксимирует T3 в зависимости от Tnv
 
//if (f_start)//1-й запуск
//{
//Tnv0 60 элементов
var Tnv0 = new Array 
(9.00,8.00,7.00,6.00,5.00,4.00,3.00,2.00,1.00,0.00,
-1.00,-2.00,-3.00,-4.00,-5.00,-6.00,-7.00,-8.00,-9.00,-10.00,
-11.00,-12.00,-13.00,-14.00,-15.00,-16.00,-17.00,-18.00,-19.00,-20.00,
-21.00,-22.00,-23.00,-24.00,-25.00,-26.00,-27.00,-28.00,-29.00,-30.00,
-31.00,-32.00,-33.00,-34.00,-35.00,-36.00,-37.00,-38.00,-39.00,-40.00,
-41.00,-42.00,-43.00,-44.00,-45.00,-46.00,-47.00,-48.00,-49.00,-50.00);
 
//T30 60 элементов
var T30 = new Array 
(43.90,43.90,43.70,43.50,43.30,43.10,42.90,42.70,42.60,42.40,
42.90,43.70,44.50,45.30,46.10,46.90,47.70,48.50,49.30,50.00,
51.50,52.30,53.00,53.70,54.50,55.20,55.90,56.60,57.30,58.00,
58.70,59.40,60.10,60.80,61.50,61.80,61.90,62.00,61.70,61.10,
60.50,59.90,59.40,58.80,58.30,61.80,61.90,62.00,61.70,61.10,
60.50,59.90,59.40,58.80,58.30,61.80,61.90,62.00,61.70,61.10);
 
//рассчитываем a3=(y2-y1)/(x2-x1)
var a3=new Array();
for(var i=0; i < Tnv0.length-1; i++) a3.push((T30[i+1]-T30[i])/(Tnv0[i+1]-Tnv0[i]));
//рассчитываем последний элемент массива 
i=Tnv0.length-1;
a3.push(T30[i]/Tnv0[i]);
 
//рассчитываем b3=y1-x1*a1
var b3=new Array();
for(var i=0; i < Tnv0.length; i++) b3.push(T30[i]-Tnv0[i]*a3[i]);
 
//концовка 1-го запуска
//f_start=false;
//}
 
 
//рассчитываем j соответствующий входному Tnv
//ограничиваем пределы Tnv
if (Tnv>9.00) Tnv=9.00;
if (Tnv<-50.00) Tnv=-50.00;
 
var delta=0.00;var deltamin=abs(Tnv-Tnv0[0]);var j=0;
for(var i=0; i < Tnv0.length-1; i++)
{
	delta=abs(Tnv-Tnv0[i]);
	if (delta<=deltamin)
	{deltamin=delta;j=i;}
	else
	{}
}
 
//y=ax+b, выход функции
T3=a3[j]*Tnv+b3[j];


P.S. Статус [BugWrong] наверное преждевременный, т.к. по факту функция в библиотеке тест "Исполнить" проходит, а при первом запуске в блочном вычислителе не исполняется, пока не перезапустить контроллер блочного вычислителя вручную. Мусора в теле функции нет. Функций у меня таких в проекте 5 шт. Убрал во всех стартовую секцию, получил допзагрузку Raspberry Pi в дополнительные 20 % при отработке блочного контроллера (период 5 сек), что не есть гуд. Похоже прийдется внедрять "костыль" передергивающий контроллер блочного вычислителя.

[Сообщение редактировалось 7 раз(а), в последний раз 02.12.2014 в 18:12.]
Сообщение создано: 02. 12. 2014 [21:06]
roman
Roman Savochenko
Moderator
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
"pentagon128" wrote:

//y=ax+b, выход функции
T3=a3[j]*Tnv+b3[j];

Даже не собираюсь вникать, но точно проблема тут, а значит берите и печатайте, что в аргументах и почему в них не то, что ожидалось.

Learn, learn and learn better than work, work and work.
Сообщение создано: 03. 12. 2014 [04:58]
pentagon128
Руслан Кучерявый
Создатель темы
Зарегистрирован(а) с: 15.11.2011
Сообщения: 102
Попробую поотображать параметры в блочном вычислителе чуть позже. Пока остаётся факт. Функция в библиотеке при проверке на вкладке "Исполнить" - работает нормально. При помещении в контроллер java вычислителя работает нормально. А при помещении в блочный вычислитель - при запуске Openscada имеем inf в выходном аргументе. Т.е. имею проблему только в блочном вычислителе.

T3=a3[j]*Tnv+b3[j]

это уравнение прямой y=ax+b. в качестве a и b берутся значения из массивов.
j- индекс массива вычисления по которому наиболее близки входному значению.
Сообщение создано: 03. 12. 2014 [08:32]
roman
Roman Savochenko
Moderator
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
"pentagon128" wrote:

Пока остаётся факт. Функция в библиотеке при проверке на вкладке "Исполнить" - работает нормально. При помещении в контроллер java вычислителя работает нормально. А при помещении в блочный вычислитель - при запуске Openscada имеем inf в выходном аргументе. Т.е. имею проблему только в блочном вычислителе.

Т.е. не нужно делать "глубокомысленных" выводов не понимая, что разница в BlockCalc только в том, что он устанавливает сам "f_start" и т.д.
Поэтому проверяйте и не делайте преждевременных заключений!
Кстати проверьте прохождение "f_start" при исходных условиях запуска!

Learn, learn and learn better than work, work and work.
Сообщение создано: 04. 12. 2014 [21:02]
pentagon128
Руслан Кучерявый
Создатель темы
Зарегистрирован(а) с: 15.11.2011
Сообщения: 102
Добавил IO функции id f_start и f_stop
Проверил, в Java вычислителе на вкладке Исполнить исполнение блока кода первого запуска происходит только тогда когда на вкладке Исполнить выставить галочку f_start вручную, при этом в IO f_start должен быть по умолчанию 1, иначе получаем inf на вкладке Исполнить в случае моей функции. Логика работы вкладки Исполнить понятна - f_start приходиться включать отключать вручную. Вариант когда этого можно не делать - в конце стартового блока кода в программе указать:

if (f_start)//1-й запуск
{

//конец стартового блока
f_start=false;
}

при этом имею 120мс на первый запуск кода, и 14 мс на все последующие. Всё работает нормально. Если вызываю функцию. через контроллер Java вычислителя - всё работает. При вызове через блочный вычислитель - стартовый участок кода не выполняется при первом запуске блочного вычислителя при старте OpenScada, т.е. как будто f_start=0 всё время, посмотреть его значение при запуске OpenScada сложно, надо наверное в архив писать. Посмотрел примеры котла и компрессорной станции - в блочных вычислителях нигде f_start и f_stop + логика стартового и оконечного кода в функции не использована.

[Сообщение редактировалось 1 раз(а), в последний раз 04.12.2014 в 21:09.]
Сообщение создано: 04. 12. 2014 [22:00]
roman
Roman Savochenko
Moderator
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
"pentagon128" wrote:

При вызове через блочный вычислитель - стартовый участок кода не выполняется при первом запуске блочного вычислителя при старте OpenScada, т.е. как будто f_start=0 всё время, посмотреть его значение при запуске OpenScada сложно, надо наверное в архив писать.

Ничего сложного, добавляем:
SYS.messInfo("BlckCalc","f_start="+f_start);

Вот мои примеры (N900) в протоколе, если запускать контроллер BlockCalc:
171 4.12.2014 21:53:12 1464 BlckCalc 1 f_start=0
172 4.12.2014 21:53:11 3326 BlckCalc 1 f_start=0
173 4.12.2014 21:53:10 557800 BlckCalc 1 f_start=1

Если ставить в обработку блок исполняющегося контроллера BlockCalc:
1 4.12.2014 21:58:02 793 BlckCalc 1 f_start=0
2 4.12.2014 21:58:01 762 BlckCalc 1 f_start=0
3 4.12.2014 21:58:00 762 BlckCalc 1 f_start=0
4 4.12.2014 21:57:59 762 BlckCalc 1 f_start=0
5 4.12.2014 21:57:58 877166 BlckCalc 1 f_start=1

Продолжайте разбираться!

Learn, learn and learn better than work, work and work.
Сообщение создано: 04. 12. 2014 [22:02]
pentagon128
Руслан Кучерявый
Создатель темы
Зарегистрирован(а) с: 15.11.2011
Сообщения: 102
Вместо f_start завёл свою переменную fstart в качестве флага 1-го запуска функции. На вкладке IO функции указываю значение по умолчанию fstart=1. В теле функции имеется стартовый блок кода:

if (fstart)//1-й запуск
{

//конец стартового блока
fstart=false;
}

Функция отлично отрабатывает на вкладке Исполнить и в контроллере Java вычислителя. В блоке блочного вычислителя получаю inf ибо стартовый блок кода не работает. Параметр по умолчанию fstart=1 не передаётся на вход fstart=Свободен ,блочного вычислителя, т.е. на вкладке IO блока блочного вычислителя имеем fstart=0. Если в блоке блочного вычислителя поставить галочку и присвоить fstart=1 то стартовый блок кода отрабатывает в блоке блочного вычислителя, и inf ERROR уходит. Т.е. вижу 2 вещи:
1. f_start не отрабатывает в блочном вычислителе при старте OpenScada, при ручном перезапуске отрабатывает
2. Параметры по умолчанию аргументов функции, использованной в блоке блочного вычислителя, не передаются в блок блочного вычислителя в соответствующий IO если связь у него выставлена Свободен.

[Сообщение редактировалось 2 раз(а), в последний раз 04.12.2014 в 22:04.]



12784