首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将UML状态机转换为SCL?

将UML状态机转换为SCL?
EN

Stack Overflow用户
提问于 2017-01-19 16:45:39
回答 4查看 861关注 0票数 1

我想知道我是否可以用状态机/图对PLC进行编程。

在Sparx EA的帮助下,我们可以组成状态机。有没有可能将这个状态机转换成SCL(结构化控制语言,用于PLC编程)?或者,我们可以从Sparx EA中获取什么类型的数据,作为PLC编程的输入?

也许你有一个更好的想法来实现这个想法。

EN

回答 4

Stack Overflow用户

发布于 2017-01-19 17:53:40

好的。您需要一个代码生成器工具,它可以读取状态机图表,并生成等效的结构化文本。

代码的形状非常简单。您可以为每个位定义一个ST布尔值(如果您可以像在StateCharts中那样拥有活动的并行状态)或一个包含状态号的ST整数。

然后,每个州的ST代码为:

代码语言:javascript
复制
   if (StateXXX) then
       <action in this state>
       if (somecondition)
          StateXXX=false;
          StateYYY=true;
       endif
   endif

您需要为每个州生成此代码。

这就留下了一个问题,你使用什么工具来完成这一任务?可以说是任何可以读取UML图的工具,UML图通常可以作为XML文档从UML编辑器中导出;使用解析后的XML,您可以编写代码来爬过它并输出上面的代码片段。

如果您编写的片段是定义良好的模板,这可能会更容易。您可以使用即席模板(简单的文本字符串,其中包含必须填充某些内容的标记),也可以使用强制生成代码的结构和组合的工具,如Program Transformation System (PTS)

PTS接受一种语言的语法,将解析该语言的实例,并允许您转换该语言,最后生成修改后的语言实例。一个有用的特例是将琐碎的程序转换为复杂的、真实的程序。此外,一个好的PTS将允许您编写正式代码模板方面的模式和转换规则,至少强制模板的语法有效。这确保了您使用的片段始终具有一定的最小意义。(相反,您可以在文本模板中编写任何您喜欢的垃圾代码)。当您编写大量这样的模式时,这对避免产生垃圾非常有帮助。

对于这个特定的示例(我公司的名为DMS的PTS,请参阅bio),您可以为上面的片段编写模式:

代码语言:javascript
复制
 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是由语法定义驱动的;它已经知道XML语言,特别是对ST和40+有健壮的定义)。

票数 2
EN

Stack Overflow用户

发布于 2017-01-19 17:37:45

我从来没有真正编写过S7,但基本上知道你在找什么。EA没有用于SCL的生成器,看到它来自Sparx的机会很低。所以有两种可能性。

首先(但我不喜欢)是深入研究在代码生成过程中使用的Sparx宏语言的内部。如果你只需要对现有的模板做一些小的调整,那也没什么,但是写一个全新的模板(对我来说)一点也不好玩。

第二种方法是使用API生成代码。这相当简单(对我来说,因为我在大学里学的是编译器构造)。您要做的就是获取状态机,遍历它并生成相应的语言结构。这在很大程度上取决于你的技能,但我会在几天内创建一个粗略的原型。

Perl这里是一个示例脚本(我知道如果您一周左右不使用它,它就是一个,但是您可以破解它),它使用EA的API来解析状态机:

代码语言:javascript
复制
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;

下面是一个简单的主程序:

代码语言:javascript
复制
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 condition -> State1 (StateNode StateNode__no condition->State1)

状态State1

__condition -> State2

__exit ->状态State2

other condition -> State1 (其他条件)

第一个是未命名的出口,第二个是InitialNode (您也可以从StateNode获取该信息并使用它)。State1有两种可能的转换(到exit和State2)。而State2只会转换到State1

现在,有了命名状态列表,您可以为不同的状态创建一些枚举。此外,您还为所有转换提供了保护,您可以将其转换为if-cascades或switch-语句。

当然,这不是一个完整的代码生成器,但您可以从这个脚手架中了解如何制作一个。

票数 1
EN

Stack Overflow用户

发布于 2017-01-22 23:40:16

如果你使用的是西门子PLC-s,那么图形有一个可选的软件包,叫做S7 -S7:http://w3.siemens.com/mcms/simatic-controller-software/en/step7/simatic-s7-graph/Pages/Default.aspx。您可以在那里实现状态机。但不知道它的任何导入选项。

我将它用于一些作为状态机进行控制的设备。那个软件包不是免费的,我不记得它的价格了。我也不知道是否所有的S7家族都支持它。我使用了400系列,它在那里工作。

在任何项目中使用它之前,请询问您当地的西门子分销商,允许您使用它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41737351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档