Преобразование конечного автомата UML в SCL?
Я хотел бы знать, могу ли я запрограммировать ПЛК с помощью конечного автомата / схемы.
С помощью Sparx EA мы можем составить наш конечный автомат. Есть ли шанс преобразовать этот конечный автомат в SCL(язык структурированного управления, используемый в программировании ПЛК)? Или какие данные мы можем взять из советника Sparx, которые мы можем использовать в качестве входных данных для программирования ПЛК?
Или, может быть, у вас есть идея, как реализовать эту идею.
3 ответа
Конечно. Вам нужен инструмент генератора кода, который может читать диаграмму конечного автомата и генерировать эквивалентный структурированный текст.
Форма кода довольно проста. Вы можете определить логическое значение ST для каждого бита (если вы можете иметь параллельные состояния в реальном времени, как в StateCharts) или целое число ST, содержащее номер состояния.
Код ST для каждого состояния:
if (StateXXX) then
<action in this state>
if (somecondition)
StateXXX=false;
StateYYY=true;
endif
endif
Вам нужно сгенерировать этот код для каждого государства.
Это оставляет вопрос о том, какой инструмент вы используете для этого? Можно утверждать, что любой инструмент, который может прочитать диаграмму UML, которая обычно экспортируется как документ XML из редакторов UML; с проанализированным XML вы можете написать код, чтобы пролезть через него и выплюнуть вышеупомянутые фрагменты кода.
Возможно, это будет проще, если вы будете кодировать фрагменты, которые представляют собой четко определенные шаблоны. Вы можете использовать специальные шаблоны (просто текстовые строки, содержащие маркеры, где что-то должно быть заполнено), или вы можете использовать инструмент, который обеспечивает структуру и состав сгенерированного кода, такой как Система преобразования программ (PTS).
PTS принимает грамматику для языка, анализирует экземпляры этого языка и позволяет вам преобразовать этот язык, наконец выплевывая измененный экземпляр языка. Полезный особый случай - преобразование, если хотите, тривиальной программы в сложную, реальную программу. Кроме того, хороший PTS позволит вам писать шаблоны и правила преобразования с точки зрения формальных шаблонов кода, которые обеспечивают, по крайней мере, синтаксис шаблона, чтобы быть действительным. Это гарантирует, что части, с которыми вы работаете, всегда имеют определенный минимальный смысл. (Напротив, вы можете написать любой мусор, который вам нравится, в текстовом шаблоне). Когда вы пишете много таких шаблонов, это очень полезно, чтобы избежать создания мусора.
Для этого конкретного примера, для (PTS моей компании под названием DMS, см. Био) вы можете написать шаблоны для вышеуказанного фрагмента:
pattern StateInstance(statenumber: natural, action: statements, exit_condition: expression, exit_state: natural): statement =
" if (StateNumber=\statenumber) then
\action
if (\exit_condition) then
StateNumber=\exit_state
endif
endif
";
DMS предоставляет API для создания экземпляра этого шаблона (и других, вы обычно пишете много) и составления их результатов (используя созданные шаблоны в качестве аргументов для создания других экземпляров) для создания окончательной программы. Вы также можете добавить правило преобразования для оптимизации сгенерированного кода. (DMS управляется грамматическими определениями; она уже знает более 40 языков и, в частности, имеет надежные определения для ST и XML).
Я никогда не программировал S7, но в основном знаю, что вы ищете. У EA нет генератора для SCL, и шансы увидеть это от Sparx невелики. Так что есть две возможности.
Во-первых (но я не предпочитаю), это углубиться в интуицию языка макросов Sparx, который используется во время генерации кода. Если вам просто нужна небольшая адаптация к существующим шаблонам, это нормально, но написание полностью нового не доставляет удовольствия (для меня).
Второй способ - использовать API для генерации кода. Это довольно легко (ну, для меня, так как я изучал конструирование компиляторов в университете). Что бы вы сделали, это взять конечный автомат, пройти его и выплюнуть соответствующие языковые конструкции. Это сильно зависит от ваших навыков, но я бы создал грубый прототип через пару дней.
Edit Вот пример Perl (я знаю, что это PITA, если вы не используете его в течение недели или около того, но вы, вероятно, можете расшифровать его), который анализирует конечный автомат с помощью API EA:
package Compiler;
use strict;
use Win32::OLE qw (in);
sub new {
my ($self, $rep) = @_;
$self = {};
$self->{nodes} = {};
$self->{rep} = $rep;
bless $self;
}
sub traverse {
my ($self, $node) = @_;
my $guid = $node->ElementGUID;
return if defined($self->{nodes}->{$guid});
my $nodeInfo = { 'name' => $node->Name, 'type'=> $node->Type, 'out' => ()};
$self->{nodes}->{$guid} = $nodeInfo;
for my $trans (in $node->Connectors) {
my $target = $self->{rep}->GetElementByID($trans->SupplierID);
next if $target->ElementGUID eq $guid;
my @targetInfo = ($trans->TransitionGuard, $target->ElementGUID);
push(@{$nodeInfo->{out}}, \@targetInfo);
$self->traverse($target);
}
}
1;
и простая основная программа, как это:
use strict;
no strict 'refs';
use compiler;
my $rep = $ENV{'REP'}; # get repository pointer "by magic"
my $node = $rep->GetElementByGUID('{574C5E0C-E032-44c6-A6B0-783D35B9958B}'); # fixed addressing of InitialNode
my $compiler = Compiler->new($rep);
$compiler->traverse($node); # read in all possible transitions/states
my %states = %{$compiler->{nodes}}; # this hash holds all states and their transitions
for my $key (keys %states) {
my $state = $states{$key}; # loop through all found states
print "$state->{type} $state->{name}\n"; # state name
for my $out (@{$state->{out}}) {
my ($guard, $guid) = @{$out};
my $target = $compiler->{nodes}->{$guid};
print "__$guard -> $target->{name}\n";
}
}
Теперь предположим, что у вас есть конечный автомат, как это:
Когда вы запустите вышеуказанную программу, она напечатает
StateNode
StateNode
__no состояние -> State1
State State1
__условие -> State2
__exit ->
State State2
другое состояние -> State1
Первый StateNode - это безымянный выход, а затем InitialNode (вы также можете получить эту информацию из API и использовать ее). State1
имеет два возможных перехода (для выхода и State2
). А также State2
только проходит к State1
,
Теперь со списком именованных состояний вы можете создать перечисление для разных состояний. Также у вас есть стражи для всех переходов, которые вы можете преобразовать в if-cascades или switch-инструкции.
Конечно, это не полный генератор кода, но вы можете понять, как его создать из этого скаффолда.
Если вы используете Siemens PLC-s, то у S7 был дополнительный пакет программного обеспечения под названием s7-graph: http://w3.siemens.com/mcms/simatic-controller-software/en/step7/simatic-s7-graph/Pages/Default.aspx. Вы можете реализовать конечные автоматы там. Но не знаю никаких вариантов импорта для него.
Я использовал это для некоторого оборудования, которое управлялось как конечные автоматы. Этот программный пакет не был бесплатным, я не помню его цену. Я также не знаю, поддерживали ли все семейства ПЛК S7. Я использовал 400 серии, и это сработало там.
Попросите местного дистрибьютора Siemens позволить вам немного поиграть с ним, прежде чем использовать его в каком-либо проекте.
Мне нужно написать шаблон в EA, чтобы реализовать код PLCopen для генерации кода из диаграмм классов, конечный автомат в код ST/SCL (IEC61131 в Twincat/Codesys).
Диаграмма классов используется для описания структуры такой программы, как FB, DUT. Конечный автомат используется для описания динамического процесса для программы ПЛК. Таким образом, вся программа oop plc (с интерфейсом, наследование) будет автоматически выполняться из созданной модели UML.
https://www.youtube.com/watch?v=z071cZgMbZ8
Здесь я создал новый набор инструментов, который предназначен для моделирования для программы plc в EA.