【发布时间】:2020-07-16 02:08:38
【问题描述】:
我想知道我是否可以使用状态机/图表对 PLC 进行编程。
在 Sparx EA 的帮助下,我们可以组成我们的状态机。有没有机会将此状态机转换为 SCL(结构化控制语言,用于 PLC 编程)?或者我们可以从 Sparx EA 中获取什么样的数据,作为 PLC 编程的输入?
或者也许你有更好的想法来实现这个想法。
【问题讨论】:
标签: uml enterprise-architect state-machine plc
我想知道我是否可以使用状态机/图表对 PLC 进行编程。
在 Sparx EA 的帮助下,我们可以组成我们的状态机。有没有机会将此状态机转换为 SCL(结构化控制语言,用于 PLC 编程)?或者我们可以从 Sparx EA 中获取什么样的数据,作为 PLC 编程的输入?
或者也许你有更好的想法来实现这个想法。
【问题讨论】:
标签: uml enterprise-architect state-machine plc
当然。您需要一个可以读取状态机图并生成等效结构化文本的代码生成器工具。
代码的形式非常简单。您可以为每个位定义一个 ST 布尔值(如果您可以像在 StateCharts 中那样具有实时并行状态)或一个包含状态编号的 ST 整数。
每个状态的 ST 代码为:
if (StateXXX) then
<action in this state>
if (somecondition)
StateXXX=false;
StateYYY=true;
endif
endif
您需要为每个状态生成此代码。
剩下的问题是您使用什么工具 来完成此任务? 可以说任何可以读取 UML 图的工具,通常可以从 UML 编辑器导出为 XML 文档;有了解析后的XML,你就可以编写代码爬过去,吐出上面的代码片段。
如果您编写定义良好的模板片段,这可能会更容易。您可以使用临时模板(简单的文本字符串,其中包含必须填写内容的标记),也可以使用强制生成代码的结构和组合的工具,例如 Program Transformation System (PTS)。
PTS 接受一种语言的语法,将解析该语言的实例,并让您转换该语言,最后吐出修改后的语言实例。一个有用的特殊情况是,如果您愿意,可以将平凡的程序转换为复杂的真实程序。此外,一个好的 PTS 可以让你根据正式的代码模板编写模式和转换规则,至少强制模板的语法是有效的。这可确保您使用的作品始终具有一定的最小意义。 (相比之下,您可以在文本模板中编写任何您喜欢的垃圾)。当您编写大量此类模式时,这对于避免产生垃圾非常有帮助。
对于这个特定的示例,对于(我公司的 PTS 称为 DMS,请参阅 bio),您可以为上述片段编写模式:
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 进行代码生成。这相当容易(嗯,对我来说,因为我在大学学习编译器构造)。你要做的是获取状态机,遍历它并吐出相应的语言结构。这在很大程度上取决于您的技能,但我会在几天内创建一个粗略的原型。
编辑这是一个示例 Perl(我知道它是一个 PITA,如果你一周左右不使用它,但你可能会破译它)脚本使用解析状态机EA 的 API:
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";
}
}
现在假设你有一个这样的状态机:
当你运行上面的程序时,它会打印出来
状态节点
状态节点
__无条件 -> State1
状态 State1
__condition -> State2
__exit ->
状态 State2
其他条件 -> State1
第一个 StateNode 是未命名的出口,下一个是 InitialNode(您也可以从 API 获取该信息并使用它)。 State1 有两种可能的转换(退出和State2)。而State2 只转换为State1。
现在,通过命名状态列表,您可以为不同的状态创建一些枚举。此外,您还拥有所有转换的守卫,您可以将其转换为 if-cascades 或 switch-statements。
当然,这不是一个完整的代码生成器,但您可以了解如何从这个脚手架制作一个。
【讨论】:
如果您使用的是 Siemens PLC-s,那么 S7 有一个名为 s7-graph 的可选软件包:http://w3.siemens.com/mcms/simatic-controller-software/en/step7/simatic-s7-graph/Pages/Default.aspx。您可以在那里实现状态机。但不知道它的任何导入选项。
我将它用于一些被控制为状态机的设备。那个软件包不是免费的,我不记得它的价格了。我也不知道是否所有 S7 PLC 系列都支持它。我使用了 400 系列,它在那里工作。
在将它用于任何项目之前,请让您当地的 Siemens 经销商让您试用一下。
【讨论】:
我在 EA 中编写了一个模板来实现从类图、状态机到 ST/SCL 代码的代码生成 PLCopen 代码(Twincat/Codesys 中的 IEC61131)。
类图用于描述FB、DUT等程序的结构。 状态机用于描述plc程序的动态过程。 这样整个 oop plc 程序(带有接口,继承)将从 UML 模型中自动生成。
https://www.youtube.com/watch?v=z071cZgMbZ8
这里我创建了一个新的工具箱,专门用于 EA 中 plc 程序的建模
【讨论】: