Просмотр полной версии : Как работает шаг SFC, написанный на SFC?
Может быть, я проглядел документацию..
Но, короче, на эмуляторе получается так -- маркер управления передается во внутренний блок, проходит там один внутренний шаг и покидает блок, возвращаясь наружу. При этом позиция во внутреннем блоке запоминается. На следующем проходе маркер попадает к очередному невыполненному внутреннему шагу, делает его и снова выходит наружу.
Т.е. в программе такого вида:
OUT1
OUT2 (*OUT2 написан на SFC и состоит из шагов IN1, IN2, IN3*)
IN1
IN2
IN3
OUT3
маркер ходит так:
OUT1 =>IN1=>OUT3=>OUT1=>IN2=>OUT3=>OUT1=>IN3>OUT3 ...
Логика в этом может и присутствует, но не самая очевидная.
Вопросы:
1) Это так и есть?
2) А в каком месте это описано, ткните пож?
1 Так есть
2 Зачем описывать одно и тоже. Автоматы в ПОУ - их локальные (static) переменные. Отсюда и пляшите коли поняли
Может быть, я проглядел документацию..
Но, короче, на эмуляторе получается так -- маркер управления передается во внутренний блок, проходит там один внутренний шаг и покидает блок, возвращаясь наружу. При этом позиция во внутреннем блоке запоминается. На следующем проходе маркер попадает к очередному невыполненному внутреннему шагу, делает его и снова выходит наружу.
Т.е. в программе такого вида:
OUT1
OUT2 (*OUT2 написан на SFC и состоит из шагов IN1, IN2, IN3*)
IN1
IN2
IN3
OUT3
маркер ходит так:
OUT1 =>IN1=>OUT3=>OUT1=>IN2=>OUT3=>OUT1=>IN3>OUT3 ...
Логика в этом может и присутствует, но не самая очевидная.
Вопросы:
1) Это так и есть?
2) А в каком месте это описано, ткните пож?
Почитайте статьи Петрова на сайте Пролога http://prolog-plc.ru/pb1
начните с этой Отладка прикладных ПЛК программ в CoDeSys (часть 6) (http://prolog-plc.ru/docs/iecdeb06.pdf)
Прочел.
Но не понял, откуда вытекает что маркер пойдет так, а не прошагает весь внутренний шаг подряд. Те почему не
OUT1 =>IN1=>IN2=>IN3=>OUT3..
Видимо, я не понимаю, что такое шаг SFC, написанный на SFC. Во что "раскрывается" эта вложенная структура.
Видимо, я не понимаю, что такое шаг SFC, написанный на SFC
Вы ж вроде в жаве юзаете - банальный switch в switche. Чего непонятно-то ?
Вложенная вызывается только при вызове "владельца". "Владелец" отдыхает - все вложенные "морская фигура замри"
откуда вытекает что маркер пойдет так, а не прошагает весь внутренний шаг подряд. Те почему не
OUT1 =>IN1=>IN2=>IN3=>OUT3..
А откуда вытекает что при вызове OUT1 1 раз, он должен самовызваться 3 раза ?
Хотите что внутрянку прошагал от начала до конца - при входе в OUT1 сброс внутрянки на IN1, а в условиях выхода из OUT1 : .. AND "внутренний автомат завершил IN3". Тока получится обычный линейный switch/case c просто вынесенной частью кода
Вы ж вроде в жаве юзаете - банальный switch в switche. Чего непонятно-то ?
Вложенная вызывается только при вызове "владельца". "Владелец" отдыхает - все вложенные "морская фигура замри"
То, что он там -- это я вижу) Мне было неочевидно, что у внутреннего свой по сути источник тактовых циклов.
А откуда вытекает что при вызове OUT1 1 раз, он должен самовызваться 3 раза ?
Ващет на первый взгляд из правил перехода -- IN1 отработал, переход после него стоит в TRUE -- значит поехали туда, куда этот TRUE указывает, то есть в IN2.
Я понимаю, что это было бы засадой, потому что эти IN1 IN2 IN3 образовали бы бесконечный цикл, для отдачи управления наружу пришлось бы делать явный переход.
Хотите что внутрянку прошагал от начала до конца - при входе в OUT1 сброс внутрянки на IN1, а в условиях выхода из OUT1 : .. AND "внутренний автомат завершил IN3"
Я, еще раз -- не понимаю, из какого места в описании SFC вытекает то поведение, что есть. Это меня беспокоит, потому как я очевидно не умею это описание читать правильно.
Вот единственное что похожего нашел -- в разделе 2.6.1 собственно стандарта МЭК 61131:
If any part of a program organization unit is partitioned into SFC elements, the entire program organization unit shall be so partitioned. If no SFC partitioning is given for a program organization unit, the entire program organization unit shall be considered to be a single action which executes under the control of the invoking entity.
Деццтво какое-то.
Вы даже не различаете пользовательский цикл (из нескольких шагов, далее - ПЦ )) и сам автомат (SFC)
Впилили in1-2-3 и решили шо это и есть автомат. А это просто случайное совпадение Вашего ПЦ и шагов автомата.
Автомат не имеет начала и конца. ПЦ может начаться где угодно и закончится где угодно, иметь параллельные ветки и любую последовательность исполнения шагов. И как система определит Ваши замыслы по завершению ?
Раскройте мысль, если не трудно. Что именно вы называет автоматом -- сам движок SFC?
Он, вроде, обещано, находит активные шаги для следующего цикла из двух вещей -- активных шагов на текущем цикле, и условий перехода из этих шагов.
Когда мы перешли на OUT2, у нас два активных шага -- OUT2, и in1. Из обоих переход разрешен. Откуда вытекает то, что управление получит именно OUT3? Если можете объяснить, буду благодарен.
Что именно вы называет автоматом -- сам движок SFC?
Автомат состояния конкретного POU (на SFC)
Термин "активный" - специально придуман чтоб запудрить мозг начинающим в SFC
Есть автомат. Он указывает на кокой-то шаг. Вот и вся мифическая "активность"
Работа шага - это его вызов
Когда мы перешли на OUT2, у нас два активных шага -- OUT2, и in1.
Когда перешли на OUT2 - in'ы тупо не вызываются. Их ведь вызывает OUT1
"Активный" in - первый в очереди к зубному. А зубной - на обеде
PS
Тем кто бросается в SFC настоятельно рекомендовал бы проюзать case/switch. Просто чтоб прочуйствовать работу автоматов. И тогда снимутся все вопросы про SFC
Тем кто бросается в SFC настоятельно рекомендовал бы проюзать case/switch. Просто чтоб прочуйствовать работу автоматов. И тогда снимутся все вопросы про SFC
Вы хотите сказать, что там примерно так для SFC, вложенного в SFC ?
WHILE TRUE i := (i+1) MOD N
CASE i OF
1: Do1;
2: Do2;
2: Do3;
..
k: DoK
WHILE TRUE j := (j+1) MOD L
CASE j OF
1: DoAnother1;
2: DoAnother2;
3: DoAnother3;
..
L: DoAnotherL;
END_CASE
EXIT;
END_WHILE
..
N-1: DoN-1;
N: DoN ;
END_CASE
END_WHILE
И как с этой точки зрения выглядит jump из внутреннего блока наружу?
В такой, например, схеме:
OUT1
OUT2
in1
in2 -> OUT4
OUT3
OUT4
по наружному блоку начнет циркулировать натурально два маркера. "Активный шаг" вполне существующее понятие.
И как с этой точки зрения выглядит jump из внутреннего блока наружу?
как макароны.
Про это еще в середине XX века все сказано. Вы решили пройти весь путь с начала ?
по наружному блоку начнет циркулировать натурально два маркера.
Их может быть и больше. А зовётся это - параллельность а не вложенность. Только какой в этом смысл если набор переменных - общий
Так получается, модель со вложенными свитчами - неправда
Они нормальные вложенные свитчи пока не произойдет акт макаронизации в виде goto из вложенного цикла.
Выстрелить в ногу есть и более простые способы.
Они нормальные вложенные свитчи пока не произойдет акт макаронизации в виде goto из вложенного цикла.
Выстрелить в ногу есть и более простые способы.
Да не в стиле программирования вопрос. Формальное описание-то есть у этой конструкции, у вложенных SFC?
Там же http://prolog-plc.ru/docs/iecdeb06.pdf
21225
Там же http://prolog-plc.ru/docs/iecdeb06.pdf
21225
Да, конечно. Но разве вложенный блок эквивалентен параллельной ветке?
Я просто пытаюсь понять, каким формальными правилами описывается этот самый вложенный блок. Ну, раз есть конструкция, должна же она быть описана. Тот же стандарт МЭК на целую страницу имеет примеров небезопасных конструкций -- и с размножением маркера, и с недостижимыми блоками.
А про то, как происходит передача управления во вложенный блок и возврат --нет ничего.
Наверное, это всем очевидно, а я не понимаю какой-то фундаментальной вещи про ПЛК. Я без иронии, трудности с переключением на подходы ПЛК имеются. Вот и пытаюсь докопаться до того, чего именно я не понимаю, как-то так.
Может быть, я проглядел документацию..
Но, короче, на эмуляторе получается так -- маркер управления передается во внутренний блок, проходит там один внутренний шаг и покидает блок, возвращаясь наружу. При этом позиция во внутреннем блоке запоминается. На следующем проходе маркер попадает к очередному невыполненному внутреннему шагу, делает его и снова выходит наружу.
Т.е. в программе такого вида:
OUT1
OUT2 (*OUT2 написан на SFC и состоит из шагов IN1, IN2, IN3*)
IN1
IN2
IN3
OUT3
маркер ходит так:
OUT1 =>IN1=>OUT3=>OUT1=>IN2=>OUT3=>OUT1=>IN3>OUT3 ...
Логика в этом может и присутствует, но не самая очевидная.
Вопросы:
1) Это так и есть?
2) А в каком месте это описано, ткните пож?
Прочел.
Но не понял, откуда вытекает что маркер пойдет так, а не прошагает весь внутренний шаг подряд. Те почему не
OUT1 =>IN1=>IN2=>IN3=>OUT3..
Видимо, я не понимаю, что такое шаг SFC, написанный на SFC. Во что "раскрывается" эта вложенная структура.
Не понимание, я думаю, связано с особенностью выполнения программы на SFC.
А именно в том, что в любом другом языке вся программа полностью выполняется при каждом вызове программного компонента (POU).
При вызове POU на SFC выполняются не вся диаграмма, а только действия, связанные с активными шагами (имеющими маркер).
По этому "OUT1 =>IN1=>IN2=>IN3=>OUT3.." не возможно по определению.
Предположим, что все переходы для шагов OUT1, OUT2, OUT3, IN1, IN2, IN3 заданы просто TRUE.
Когда в текущем цикле ПЛК первый раз шаг OUT2 станет активным, то будет вызвано его действие, которое "IN1=>IN2=>IN3", и в этом действии появится новый маркер, который будет жить собственной жизнью. Этот маркер получит шаг -"IN1". Вот он один и выполнится, потому как в текущем цикле "выполняются не вся диаграмма,а только действия, связанные с активными шагами". А шаги IN2 и IN3 могут быть выполнены только при следующем вызове действия "IN1=>IN2=>IN3".
Таким образом, после выполнения шага IN1 управление вернется в шаг OUT2 и если условие перехода за ним TRUE, то первый маркер перейдет к шагу OUT3. При следующем вызове программы OUT1=>OUT2=>OUT3 активным будет уже шаг OUT3, а не OUT2.
Вот и получится "OUT1 =>IN1=>OUT3=>OUT1=>IN2=>OUT3=>OUT1=>IN3>OUT3 ..."
ЗЫ. Важно!
Даже если переход в текущем вызове имеет значение TRUE, то следующий шаг (который за переходом) начнет работу при следующем вызове POU, а не в текущем.
По этому "OUT1 =>IN1=>IN2=>IN3=>OUT3.." не возможно по определению.
Да, это бесспорно.
Таким образом, после выполнения шага IN1 управление вернется в шаг OUT2
Вот этот момент и кажется мне плохо освещенным. Ведь, казалось бы - есть активный шаг IN1, есть разрешенный переход на IN2.
Всем спасибо, потихоньку укладывается в голове.
Бвахахахаха жесткач. Смарите пацаны чё натворить можно:
21231
Открываем стандарт, 2.6.5 Rules of evolution
Evolutions of the active states of steps shall take place along the directed links when caused by the clearing of one or more transitions.Очевидно, с позиции внешнего автомата данное правило нарушается. Ну а с позиции внутреннего автомата нарушается 2.6.3 Transitions:
A transition represents the condition whereby control passes from one or more steps preceding the transition to one or more successor steps along the corresponding directed linkВ результате внешний автомат получает два (минимум) активных шага вопреки условию перехода, а внутренний автомат остаётся без активности. А всё почему? Да потому что кто-то позволил писать в это поле что попало:
21232
... и почему-то сделали так, что шаги автоматов всей иерархии оказываются в одной области имён. Хм, а я знаю почему: потому что шаги включаются в область имён вышестоящего POU как самостоятельные имена. Если бы разработчики компилятора не поленились и ввели бы отдельные структуры для каждого автомата или не рассматривали шаги как именованную единицу компиляции, такой фигни бы не было.
Выходит, что с кодесисом надо очень чётко разделять вопросы «как работает» и «как формально описывается». Я бы сказал, что переход маркера из автомата в автомат в рамках стандарта рассматривать вообще нет смысла — это не допускается определениями переходов и порядка вычисления. При этом правила не запрещают вкладывание SFC в SFC и напоминают, что даже при соблюдении всех правил возможно сформулировать в принципе нефункционирующий и/или самоблокирующийся автомат, только среда исполнения должна считать возникновение такой ситуации ошибкой:
The application of the rules given in this subclause cannot prevent the formulation of “unsafe” SFCs, such as the one shown in figure 18 a), which may exhibit uncontrolled proliferation of tokens. Likewise, the application of these rules cannot prevent the formulation of “unreachable” SFCs, such as the one shown in figure 18 b), which may exhibit “locked up” behavior. The programmable controller system shall treat the existence of such conditions as errors as defined in 1.5.1.Проект прилагается к посту. Для воспроизведения проблемы открыть визуализацию и воспользоваться кнопками: один раз Next outer, три раза Next inner.
У меня претензии, если есть, то скорее к стандарту --- конструкция из вложенных SFC функционирует недостаточно очевидно, а кларификаций никаких нет.
Еще на SFC можно нарисовать action. Думаю, там меня тоже ждут открытия ))
Да потому что кто-то позволил писать в это поле что попало:
Классический goto из внутреннего цикла.
Смарите пацаны чё натворить можно
Можно еще сделать goto внутрь )))
Видимо среда считает что кому-то это нужно. Типа пока маркеры не слиплись, одного еще можно отравить домой.
В action - такие goto нормально заблокированы. Но все равно накосячили с локализацией имен.
Зачем мусолить косяки разработчиков. Косяк не есть предмет для РЭ, о косяке нужно предупредить "вне перехода переходить запрещено, сетку на разделителе прокакали". А дальше - сами.
Видимо среда считает что кому-то это нужно.Не уверен насчёт «считает». Сдаётся мне, такие возможности не задумывались. Просто все шаги в одну кучу сваливаются. Вот сообщение, которое выдаёт всю костыльную сущность компилятора:
21248
Надо будет в третьем кодесисе попробовать.
Не уверен насчёт «считает». Сдаётся мне, такие возможности не задумывались. Просто все шаги в одну кучу сваливаются. Вот сообщение, которое выдаёт всю костыльную сущность компилятора:
21248
Надо будет в третьем кодесисе попробовать.
Это не ошибка компилятора.
Имя шага тоже переменная (тип BOOL). Только не явная.
21249
Она доступна даже из вне POU, в вызывающей программе,например, можно узнать какой шаг внутри программы STC активный.
Или ее можно было использовать в Вашем примере с размножением маркеров, для того, чтобы их "склеить".
Или вот например
21250
В моем случае маркеры параллельных ветвей "склеятся" после выполнения шага "OSTANOV"
Это не ошибка компилятора.
Имя шага тоже переменная (тип BOOL). Только не явная.Да, я ещё вчера сказал, что «шаги включаются в область имён вышестоящего POU как самостоятельные имена». Прошу обратить особое внимание на текст сообщения компилятора: «Duplicate step name». И указывает это сообщение на шаг, а не на явно объявленную переменную типа INT. В корректной реализации с «неявными» переменными должно быть либо другое сообщение, либо декорирование имён шагов целиком (приписывание всяких прочерков и т.п. примерно как это описано в вашем источнике).
Вообще для оценки компилятора я призываю всех ссылаться на стандарт и на поведение других компиляторов, а не на справочные руководства третьих лиц, какими бы хорошими они ни были.
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot