PDA

Просмотр полной версии : SFC внутри SFC



drvlas
19.09.2011, 16:37
Здравствуйте!

У меня часть программы пишется на SFC. Мне было бы удобно, чтобы один из шагов содержал в себе действие, написанное тоже на SFC. При этом данное действие (назовем это условно "пуск двигателя") имеет такую структуру, что выполняется за много циклов программы. То есть там свои задержки, свои события, которых ждем и так далее - полноценная многошаговая SFC програмка.

Возник вопрос:

Если известно точно, что действие "пуск двигателя" не выполняется за 1 цикл, то где его лучше разместить - как входное, выходное или связанное N-действие? По смыслу, когда "пуск двигателя" отработает, мне нужно ждать некоего сигнала готовности и переходить на следующий шаг "родительского" процесса.

Я прилепил картинку, не знаю, поможет ли. Здесь я для примера из Step2 огранизовал входное действие (тот самый "пуск двигателя), а в нем какая-то накрученная муть. Требуется, чтобы при активизации Step2 начинала работу эта муть - и работала себе по циклам процессора, пока не выполнит весь "пуск двигателя". А "папа" этого процесса, шаг Step2, как предполагается, следит за условием окончания (обозначил на рисунке "R") и при выполнении - передает активность шагу Step3.
Процесс же "пуск двигателя" стоит в ожидании. И в следующий раз при активности шага Step2 будет выполнено какое-то условие активизации "пуска двигателя" и действие начнет свою работу.

Я пробовал построить модель, но не хватает ума и усердия. Даже порождение альтернативной ветви вызывает у меня судороги :) С трудом нашел, как это сделать...
Думаю, а вдруг это все не правильно и так нельзя делать?

drvlas
19.09.2011, 17:22
Если известно точно, что действие "пуск двигателя" не выполняется за 1 цикл, то где его лучше разместить - как входное, выходное или связанное N-действие?

Извините за поспешный вопрос! Все же сделать модель оказалось не так сложно (прилагается).
Ответ на мой вопрос таков: Входное (думаю, что и выходное) действия выполняются 1 раз. Поэтому, если поместить в них действие, представляющее многошаговую (точнее - многоцикловую) программу, то она не сможет выполниться при однократной передаче маркера вызывающему шагу.
Нужно размещать многоцикловое SFC-действие в связанное действие (как в моем примере wBS), повторяющееся многократно, пока родительский шаг активен.

Уважаемые модераторы, тему можно чикануть полностью... У меня не получается удалить все.

swerder
19.09.2011, 18:26
вопрос исчерпан? так бы подсказал

drvlas
19.09.2011, 18:39
вопрос исчерпан? так бы подсказал

Йо, так подскажи! У меня тут сколько открытий в ходе моделирования...

Нет, правда, если поделитесь любой инфо по SFC, буду очень рад.

swerder
20.09.2011, 10:04
как делаю я:
главная управляющая sfc диаграмма максимально упрощена, вызывает "подпрограммы действий" написанные так же на sfc. вызов происходит при переходе по каким-то условиям в шаг вызова подпрограммы, в шаге (не входное, не выходное, связанное действие) переменная "программа_действия" принимает значение true. эта переменная является разрешением на выполнение "подпрограммы".
как только "подпрограмма" выполняет весь свой алгоритм, взводит свою переменную "все_сделано".
теперь возвращаемся к главной sfc. условием выхода из шага активации подпрограммы как раз является та самая переменная "все_сделано". деактивация подпрограммы у меня сделана в следующем шаге после активации (в принципе можно и в выходном действии шага активации) - "программа_действия" принимает значение false.
подпрограмма получив false обнуляет свою переменную "все_сделано" и переходит на шаг init, где ожидает следующего вызова.
упростив вышесказанное получаем:
имеем 2 sfc программы. одна вызывает другую. в шаге вызывающей устанавливается true на переменную разрешения работы вызываемой программы, выход из шага и, соответственно, обнуление переменной происходит по условию все_сделано = true.
вызываемая прога работает пока "можно_работать" = true. доработала до конца - все_сделано := true.

Александр Приходько
20.09.2011, 10:28
Если есть сложности с пониманием - а как оно работает, как взаимодействуют ФБ и программа, я очень советую на первых порах пользоваться средствами отладки.
Это не сложно! При этом вы ивидите как работает программа и как она взаимодействует с ФБ.

алгоритм отладки прост:
1) Пуск программа - на ПЛК или в эмуляции
2) Меню онлайн - диалог точек останова. Через данное меню вы в вашем проекте ставите точку, в которой программа контроллера приостановится и будет ждать пока вы ее не запустите или не будете выполнять ее по шагам.
3) После выбора точки останова ваш проект приостановится в том месте, где вы поставили точку останова.
4) Теперь по шагам нужно выполнять ваш проект. Можно проверить как работает весь алгоритм в целом: Онлайн - шаг поверхностный. Или можно проверить как работают и ФБ - онлайн шаг детальный.

Во втором случае вы будете перемещаться по программе от одного шага к другому, при этом отрабатывать алгоритм всех ваших ФБ.

В первом случае вы не заходите в сами ФБ, но они все равно выпоняются, вы лишь только видите результат его работы (например состояние выходов).

Не поленитесь. В свое время мне это очень помогло.

drvlas
20.09.2011, 11:26
Спасибо откликнувшимся!
В обратном порядке:



я очень советую на первых порах пользоваться средствами отладки.
...
Не поленитесь. В свое время мне это очень помогло.

Да, я так и сделал. Отладкой пользуюсь (я уже кое-как на ST шкарябаю проги), вопрос был только в создании грамотного примерчика на SFC. Ну, глаза боятся, руки делают...
А вообще, когда перестал бояться и сделал именно SFC в SFC - какая красота! И настолько все прозрачно, что действительно слаборазвитые средства автодокументирования в Кодесис уже не кажутся таким уж недостатком.
SFC forever!

И сделал я примерно то, что описал уважаемый swerder:

как делаю я:
Хочу поподробнее сравнить со своей реализацией (пока только в примере, в основной программе все еще только пишется), поэтому беру небольшой таймаут.

drvlas
20.09.2011, 12:55
Вот что я понял о вызове SFC программы "дочки" из SFC "папы".

1) Переход на дочерний процесс - в связанном действии "папы". Разовые (входное и выходное) действия не позволяют "дочке" выполнить многотактовую работу.
Как только "дочка" активизирована, маркер начинат там бегать своей жизнью.
ВАЖНО: И основной процесс тоже продолжает работать. Из этого вывод:

2) Нужно позаботиться, чтобы вызывающее действие продолжало выполняться до тех пор, пока "дочка" не отработает полностью.
Простейшая реализация (но не единственная при МЭК-шагах): сделать вызывающее действие типа N, но при этом тормознуть "папу" на данном шаге.
Я ввел общую переменную, которую можна назвать "Команда-отчет", пусть это будет
FE_Cmd
По-моему, уважаемый swerder работает с разными переменными, но это не принципиально.

3) Запуск дочернего процесса. Во входном действии "папы" даем команду:

FE_Cmd := CMD_GO;

Это не все. "Дочка" еще не активирована. Но весь дочерний модуль реализован в связанном действии данного шага "папы". Поэтому активизация шага "папы" тут же активизирует связанное действие - и "дочка" увидит, в том числе, и изменение переменной FE_Cmd.
По ней "дочка" соскакивает с шага ожидания, условие выхода:

FE_Cmd = CMD_GO

... и начинает работу.
Что у "папы" в это время происходит? А программа крутится. Значит, вызывающий шаг родительского процесса может стать неактивным! Вот почему, как и уважаемый swerder, я ставлю условием выхода из данного шага:

FE_Cmd = CMD_DONE

4) Когда дочерний процесс все отработал, то управление зацикливается на шаг ожидания, а в выходном действии последнего активного шага ставим:

FE_Cmd := CMD_DONE;

5) Еще одна интересная штучка. Коллега swerder пишет:

вызываемая прога работает пока "можно_работать" = true. доработала до конца - все_сделано := true.
У меня реализовано, что дочерний процесс может состоять из нескольких частей работы, то есть умеет приостанавливаться и запускаться из РАЗНЫХ шагов родительского процесса. То есть, "дочка" доработала до окончания первой части, передает сигнал CMD_DONE и тормозит. Родительский шаг по этому сообщению деактивируется, процесс пошел, а "дочка" заморозилась. На некотором шаге родительского процесса вновь активизируется "дочка". И вот здесь я использую то, что "дочка" активизируется не с шага ИНИТ, а именно с того шага, на котором ее остановили. Поэтому она продолжает свой долгий путь.
Так реализуется, по сути, параллельное существование основного и дочернего процессов, где окончание активности дочернего может быть не финалом, а лишь паузой.

Много слов... Картинок готовых нет. Если надо будет - будем рисовать :)

swerder
20.09.2011, 14:44
2) в простом sfc - вызов дочки связанным действием, сразу после шага условие окончания работы дочки. в МЭК-SFC переменная с классификатором S, по условию окончания работы дочки - переменная с классификатором R.
4) выходное действие отрабатывает только при наступлении активности следующего шага диаграммы, а когда она настанет уже зависит от ситуации.
5) а смысл? разрежьте эту дочку на несколько частей и вызывайте каждую часть тогда когда надо.
гораздо проще будет использовать дочки-SFC как законченный кусок алгоритма, а не склеенные части с замораживанием.

drvlas
20.09.2011, 15:28
5) а смысл? разрежьте эту дочку на несколько частей и вызывайте каждую часть тогда когда надо.
гораздо проще будет использовать дочки-SFC как законченный кусок алгоритма, а не склеенные части с замораживанием.
Ну, проще или нет - зависит от логики программы. Если у меня, скажем, дочерний процесс суть управление системой подачи продукта, подталкиваемый несколько раз в ходе главного технологического процесса (цикла работы родительского), то логически это один объект. И дробить его не очень хочицца :)
Кроме того, у меня еще 2 процесса претендуют на такую же роль - подчиненных, идущих по "поджопникам" от основного процесса. Получается, что дробить - порождать кашу процессов.

Но Вы подали интересную идею вот здесь:

2) в МЭК-SFC переменная с классификатором S, по условию окончания работы дочки - переменная с классификатором R.

Ага, говорю я! А почему Stored? А потому что снимать активность с дочернего процесса вовсе не обязательно. Ведь мы обмениваемся командой-отчетом, по которой дочерний процесс все равно будет стоять на одном шаге, пока "папа" не скажет Go-go-go!
Правильно. Дочерний процесс можно просто 1 раз запустить - и не снимать с него активности.
Но тогда, дорогой коллега, мы приходим вот к какой чудной организации:

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

Мысленным взором рисую: Все "дочки" имеют в шаге ИНИТ условие перехода, которое по старту не выполняется. А "папа" работает в поте лица с самого начала. Потом "папа" доходит до шага, где нужна помощь "дочки Маши". На этом шаге он дает кототкую команду ГОУ той "дочке", что именно здесь хорошо шарит. И свое продвижение тормозит (или даже не тормозит, если сей момент "дочкиного" результата ему не нужно!). Когда "дочка Маша" выполнит свою задачу или часть задачи, она рявкнет в ответ ГОТОВО и "папа" пойдет далее. На его тернистом пути встречается новая трабла - он подключает "дочку Дашу"... И так далее.

Как замечательно! Жаль, что это и так ясно тем, кто работает с SFC :)
Но новичку это просто откровение...

Еще раз спасибо swerder-у!

swerder
20.09.2011, 15:47
во второй части поста чувствуется умудренность семейным опытом)
по первой: конечно все зависит от процесса. у меня последовательный алгоритм выполнения технологической задачи с похожими (но не одинаковыми) повторяющимися кусками алгоритма, которые я выделил в отдельные подпрограммы. тем самым получил не 1 диаграмму длиной в километр и с ничтожной удобоваримостью, а одну маленькую управляющую диаграмму, которая манипулирует этими "кусками"

drvlas
20.09.2011, 16:18
У меня пока одна дочка. И сын. Но "сыновий процесс" как-то не прижился ни в технике, ни в экономике. С чего бы это?


у меня последовательный алгоритм выполнения технологической задачи с похожими (но не одинаковыми) повторяющимися кусками алгоритма

Ну да, тут ясно. А я вот очаровался возможностями по организации действительно параллельной работы нескольких процессов. Причем, ИМХО, это выгодно отличается от параллельных ветвей в одном программном модуле именно простотой проектирования этих дополнительных процессов.
И, главное, как это изящно выглядит (спасибо SFC)! И не требует заоблачной квалификации. Это уже фича КДС.

Да, тему уже можно назвать "Организация параллельной работы взаимосвязанных процессов в SFC". Или "Взаимосвязь параллельных процессов в SFC" Как-то так.

ОК, вопрос решен. Пора воплощать :)

drvlas
22.09.2011, 10:55
Возник новый вопрос от новичка в SFC.

Есть программа из некоторого количества шагов. Допустим, прокрутка всей программы - это выполнение какой-то работы электромеханическим устройством, со своими паузами, ожиданиями датчиков и прочее.
Но принято, что в любой момент может быть нажата кнопка СТОП, по которой нужно срочно-припадочно перейти в состояние остановки, приведя попутно все механизмы в исходное состояние. И хотя механизмы можно приводить в течение необходимого времени, сама реакция на кнопку должна быть мгновенной.
Как это делается в обычном программировании - ясно. А как изящно сделать в SFC, я не пойму.
Сначала я принял идею вводить проверку специального флага в каждом из переходов. Но по мере роста программы выяснилось вот что. Если в основном SFC POU поставить такие "проскоки", то там маркер пройдет быстренько по всей ветке и достигнет шага отработки СТОПа. А вот все вызываемые действия, как оказалось, требуют такого же механизма...

Обломно как-то сделалось :( Может есть принципиально иной механизм?

swerder
22.09.2011, 11:08
у меня во всех местах, где надо контролировать ошибки/остановку, сделаны такие переходы на шаги обработки ошибок/остановки

drvlas
22.09.2011, 11:18
у меня во всех местах, где надо контролировать ошибки/остановку, сделаны такие переходы на шаги обработки ошибок/остановки
Красиво выглядит. Я не знал даже, что из одного шага можно сделать несколько выходов. У меня все как колбасища :)
Нужно, конечно, еще посмотреть, как это будет в реализации. По количеству ручной работы никак не меньше, чем добавлять по OR в мои переходы. Но, пожалуй, это все же нагляднее. А я и ценю SFC за наглядность.

Спасибо!

Принципиально других механизмов нет, как я понял. ТИПА, есть где-то процесс, мониторящий событие (кнопку), и он умеет сдернуть любую SFC-петлю в указанное сосояние. Фантазии...

swerder
22.09.2011, 14:34
для того, чтоб "сдернуть любую SFC-петлю" в другой шаг, нужен переход. чем больше мест, где надо дернуть, тем больше ручной работы

drvlas
22.09.2011, 14:53
Вот я же об этом и говорю. А представь себе параллельно (условно, конечно) работающую функцию, которая умеет делать удивительную вещь: находить активный шаг любой SFC-проги, делать ее неактивной и наоборот, активизировать нужный шаг.

Теоретически, как следует из страницы 156 ("Механизм управления шагом") книги нашего уважаемого И.Петрова, можно обратиться ко всем переменным с именами шагов, найти ту, что нужно деактивировать и "фальсифицировать" ее. Попутно и ту, что с подчеркиванием. А потом установить в TRUE переменную, отвечающую за активность нужного шага. Не ясно, что делать со _Step1 из того же примера И.Петрова. Как отработаются входные-выходные действия задеяных шагов. И т.д...

И.Петров очень не рекомендует юзать такой способ. Хотя его аргумент мне не кажется очень убедительным в данном конкретном случае. Ведь речь идет не об общем построении программы, а всего лишь об отработке "исключений".

Вот такое кто-нить вытворял?

swerder
22.09.2011, 15:06
я такое пытался вытворять при отладке программы, чтоб начинать каждый раз не сначала, а как бы с нужного момента. ничего хорошего с этими неявными переменными у меня не получилось, на том и забил.

drvlas
22.09.2011, 15:10
То есть, проба не вышла. Каких-то принципиальных вещей ведь не открылось, почему так НИЗЗЯ? Или?

Я попробую в своей тестовой (основную уже боюсь трогать) проге чей-то покрутить. Но в том-то и прелесть форума, что он может существенно сократить ненужные шишки :) Подожду ще чуток, мож прочтет кто из получивших не только шишки, но и орешки.

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

drvlas
22.09.2011, 15:28
Я попробую в своей тестовой
Ага, ЩАС.
4755
Что-то я у И.Петрова не понял. КДС не позволяет объявить переменную с именем, совпадающим с именем шага. А без этого как ее увидеть?

Пробовал присвоить иной переменной значение, так пишет, что невозможно преобразовать данные из формата SFCStepType в тип BOOL
4756

Напьюсь с горя. Сегодня ДР, так что пора наливать :)

swerder
22.09.2011, 16:31
c праздником!:)
по поводу первой картинки - если не ошибаюсь, в МЭК неявные переменные типа step.x уже заданы, объявлять не надо.

drvlas
22.09.2011, 17:21
в МЭК неявные переменные типа step.x уже заданы, объявлять не надо.
Вроде да, хотя сказано, что это "для упрощенной реализации SFC". Я ЩАС ткнул - понимает и с МЭК-шагами. Нужно разбираться. Но ведь главное - не скрыты ли такие подводные камни, что потопят все судно, когда мы его ромом нагрузим? Вот почему взываю к опытным мореходам.

Еще уважаемый И.Петров пишет об SFCInit и SFCReset. Тоже вариант. И тоже стремный, как пишет автор.

swerder
22.09.2011, 18:25
отсюда вывод: во избежание скрытых "странностей" в поведении программы следует писать программу максимально упрощенно, без всяких отладочных примочек, которые используют только "опытные программисты" (из статей И. Петрова)

drvlas
23.09.2011, 08:34
отсюда вывод: во избежание скрытых "странностей" в поведении программы следует писать программу максимально упрощенно, без всяких отладочных примочек, которые используют только "опытные программисты" (из статей И. Петрова)
Здесь я могу поспорить. Если есть понимание поведения программы при использовании "примочек", то вполне можно их использовать. Иначе мы приходим к примитивному программированию.
Простой пример из здешней жизни. Когда-то на форуме шла речь об использовании указателей. И кое-кто из уважаемых коллег заявлял, что это тоже "примочки", что с ними надо бы поосторожней. В то же время я их использую и хорошо себя чувствую.

Поэтому, ИМХО, вопрос только в степени понимания. Я надеюсь, что мы здесь разберемся и получим ответ, например, на вопрос внешнего управления активизацией и дезактивацией шага.

А может быть коллеги подскажут и иные пути. Повторюсь (ибо за многими словами задача теряется), сейчас цель состоит в том, чтобы найти способ изменения хода выполнения SFC-программы по событию. И при этом не ставить в каждом переходе ручками дополнительное условие.

swerder
23.09.2011, 09:47
вам не кажется, что поставить в каждом переходе дополнительное условие куда проще, чем теми же ручками "по событию" изменять неявные переменные состояний каждого шага?

drvlas
23.09.2011, 09:56
вам не кажется, что поставить в каждом переходе дополнительное условие куда проще, чем теми же ручками "по событию" изменять неявные переменные состояний каждого шага?

Нет, не кажется, уважаемый коллега swerder. Я думаю, что неявные переменные можно обработать в специальном действии, которое будет активно всегда. Эдакий отработчик события. И там требуется создать цикл просмотра всех шагов на предмет активности. И выключать тех, которые еще не знают о событии.
Конечно, если образовать цикл по преребору всех шагов не удастся, то получится в этом отработчике огромная колбаса перебора. Это уже ручками. Плохо. Но все равно, это собрано в одном месте, это однотипно, это копипастится, это можно просмотреть-проконтролировать визузуйно :) Думаю, что даже и в таком случае выигрыш в надежности и читабельности есть.
Вопрос открыт: кто может поделиться положительным опытом управления шагами?

capzap
23.09.2011, 10:08
к учебникам по сименсу надо обратиться, помнится что то такое я делал, по нажатию кнопки, происходило некое подобие прерывания, выполнялся код на SCL, далее подтвержалось выполнение задачи и происходил возврат в SFC

swerder
23.09.2011, 11:01
тогда я вообще не понимаю, зачем использовать SFC с такими костылями:confused: воспользуйтесь case'ом в st и прыгайте в нужное состояние когда надо

drvlas
23.09.2011, 13:44
воспользуйтесь case'ом в st и прыгайте в нужное состояние когда надо
После того, как я очаровался наглядностью и удобством программирования сложных автоматов на SFC? Нет уж, я поищу подробную информацию по костылям.
И тогда костыли превратятся в жигули. Это не мерседес, конечно, но ехать - не хромать :)

Если без шуток-прибауток, то скажу так: я считаю осмысленное применение неочевидных методов программирования вполне допустимым. Пока мы вместе с вами не очень осмыслили. Но это закрывает пути к истине.

swerder
23.09.2011, 15:45
тогда копайте на http://forum-ru.3s-software.com/index.php

drvlas
23.09.2011, 16:01
Угу. Справка:

Там сейчас 6 человек, из них зарегистрированных - 2 (я один из них)
Здесь на воруме ОВЕНа (не сильно живеньком, кстати) - 192 пользователя и 896 гостей.

Я схожу, конечно. Раз здесь больше не наливают....

swerder
23.09.2011, 16:56
зато официальный форум кодесиса:)

drvlas
24.09.2011, 20:38
ОК, приглашаю для продолжения дискусси на том форум (http://forum-ru.3s-software.com/viewtopic.php?f=1&t=1102).

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