面向对象的工业程序设计(OOIP)

 

前言

一个控制系统是由不同的部件(component)构成的。比如一个典型的控制系统由若干台PLC ,传感器,执行部件和上位PC 机组成。因此,一个控制架构也应该是由组件构成,将组件的数字化模型对应地称为“对象”。面向对象程序设计的方法是在1990年代开始被计算机科学家提出来,目前已经被广泛地使用,它使用了类,分装,继承,实例化,多态等概念和技术实现了复杂软件的模块化,分层化,重用化(reuse)。提高了软件开发的可靠性和效率。

相对而言,由于OOP复杂性和缺乏支持的图形语言环境,它在工业控制中的应用一直很缓慢。工业软件供应商开始解决这些问题,它们希望为工业控制领域提供许多OOP好处,而没有复杂性。正是应为如此,在工业软件领域的面向对象程序设计方法和信息技术领域的OOP 是不相同的。为了有所区别,人们将前者称为OOIP(OBJECT-ORIENTED INDUSTRIAL PROGRAMMING),即面向对象的工业程序设计。

 

信息技术领域的OOP和工业领域的OOIP 的主要区别

工业控制和计算机科学界在OOP解释上往往有所不同。

OOP面向对象:

  • 包括全套的计算机科学OOP功能
  • 主要基于文本
  • 通常是受过高等教育的计算机科学家的领域。

OOIP:

  • 能够使用封装,实例化和抽象的概念将功能块(FB)实例化为其他FB
  • 主要基于图形
  • 只需很少的培训,即可由控制工程师和工厂技术人员使用。

OOIP 的演进

        在工业自动化的早期,编程是扁平化的。程序员读取输入,缩放输入,对输入生成警报,执行控制算法以生成输出,对输出进行警报,缩放输出,并使用内存映射的输入/输出(I / O)值写入输出。而且大量使用全局变量。后来引入了功能/子程序,允许合并一些重复的代码,但是过程仍然是扁平化的顺序程序设计方式。

          PLC 中的梯形图编程就是典型的扁平化设计方法,程序固定周期从左到右,从上到下 周期性地执行。这种方式简单易学,长期以来受到控制工程师的喜爱。对于一些小型控制任务而言,这种扁平化的图形编程方法是非常直观和简单明了的方法。但是,这种方式显然难以实现重用(reuse),即便是一个有经验的程序员编写一个新的控制程序时,也必须从新编写所有的程序。  而且,对于一个相对复杂的控制程序。这样扁平化的程序变得十分复杂。修改程序也非常困难。

IEC61131-3 的软件模型

    之后,人们在PLC 中引入了TASK 的概念,将程序能够分成若干个TASK,第一个任务将读取所有输入,下一个任务将调整所有输入,下一个任务在调整的点上执行警报,依此类推,这种面向任务的集中式方法比扁平化方法有了很大的进步,但是当向程序中添加新功能时,它需要修改每个任务。

LD 的缺陷

   1. 信息的低密度。 导致LD设计可能会分布到数10页上,很难或不可能看到和理解全局;

  2. 不同层次的细节混杂在同一层次上会十分混乱,这使设计难以理解和维护。特别是逻辑程序和硬件控制程序是完全交织在一起的,所有程序的分层和重用非常困难。

      笔者曾经看过一个控制工程师编写的机械臂上下料的梯形图程序有十几页。非常难以读懂。他自己现场修改也很费劲。

        计算机科学的成果表明采用模块化(Modulariy)是解决这个问题的主要方法。模块化程序设计的主要手段就是将程序根据实现的功能划分成为多个功能(function,也称为函数)。这样就可以实现程序的重复使用(reuse)。修改函数内部程序不会影响应用程序的改变。并且可以建立程序库,给多个程序员应用和分享。随着结构化程序设计技术的进一步研究,计算机科学家提出程序应该更加内聚, 数据和处理他们的程序应该封装在一起更有效,全局变量要尽量地减少。渐渐地他们形成了面向对象程序设计的理念。

    在现代控制系统中,软件越来越重要,而且越来越庞大。因此,导入计算机领域行之有效的OOP 方法就显得十分重要。控制领域的标准化组织,厂商也不断地做这样的努力。IEC61131-3 的2012 (第三版)中增加了对面向目标程序设计的内容。codsys 提出了连续功能图(CFC )实现图形化OOP。而IEC61499 更是从一开始就支持面向对象程序设计的理念,复合功能块,子应用,ECC ,算法等概念与OOP 的理念非常地契合。

为了实现OOIP,控件工程师需要掌握两个关键的OOP概念:封装和实例化。

封装

封装允许创建包含控制其匹配工厂对象所需的所有功能和数据的对象。用户不需要了解或理解底层实现;他们只是使用它。一个很好的类比是汽车发动机。发动机封装了活塞,阀门,轴承和许多其他物体以及复杂的功能。驾驶员不需要知道发动机的工作原理。他们只需要了解其接口并与之交互:启动器和油门踏板。

实例化

实例化是声明和使用一个对象的多个副本而无需制作该对象的副本的能力。在IEC 61131-3编程语言中,这些对象称为“功能块”。功能块是数据类型,就像整数或实数是数据类型一样。例如我们编写了一个PID 功能块,可以在应用程序中定义多个PID 功能块的实例,通过修改参数,实现控制多个控制回路。

抽象,嵌套,接口

封装和实例化的使用导致了其他三个OOP概念的使用。第一个是抽象,即将细节按层次结构中的级别进行分组,因此程序员只需要处理设计的任何一个级别上的相关复杂性级别。第二个是嵌套,它允许对象实例化其他对象。第三个是接口,它提供了与层次结构中下一级交互的简化方法。

以汽车为例,车辆具有发动机,该发动机具有起动器,该起动器具有电枢,该电枢具有铜线,该铜线在某些位置被开采和提炼。在细节层次适合层次结构中的层次时,抽象可以将嵌套的引擎复杂性及其铜的挖掘留给其他人。用户只需要知道发动机的接口-起动器和油门踏板。

OOIP使用相同的概念。在顶层,工厂对象可以嵌套(实例化)两个反应斧对象,每个反应斧对象都抽象出了两个螺旋搅拌对象的复杂性,每个螺旋搅拌对象都嵌套了电动机和轴编码器对象。电机对象包含控制该电机所需的所有功能。

由于抽象,在层次结构的任何级别上唯一需要关注的是与下一个级别的接口。例如,螺旋搅拌将具有用于打开电动机的输入接口和用于反馈来自轴编码器的脉冲的输出接口。在反应釜级别,无需了解或处理任何潜在的复杂性,例如启动电动机或生成警报。

有一个例外是,是否需要知道电动机是否已启动,如果螺旋搅拌具有多余的电动机,情况就是这样。但是,在这种情况下,附加功能将被抽象为附加的层次结构层。代替螺旋搅拌实例化一个电动机,它将实例化一个冗余电动机,该冗余电动机将实例化多个电动机本身,以及在主电动机发生故障时启动备用电动机的逻辑。螺旋搅拌的接口仍然仅是运行电动机的命令。每个级别都封装了它可以实现的所有功能,并且仅针对其自身无法完成的任务寻找更高的级别。

基于IEC61131-3的 OOIP

IEC61131-3 标准中规范了下面五种PLC 编程语言:

  • 指令表(Instruction List Diagram,ILD)

  • 梯型图(Ladder Diagram,LD)

  • 功能块图(Function Block Diagram,FBD)

  • 结构化文字(Structured Text Language,STL)

  • 顺序功能图(Sequential Function Chart,SFC)

在FBD 之上,codesys 还提出了扩展的连续功能图(CFC)。但没有正式成为IEC 61131-3的一部分。所以一共有6种编程方式,其中指令表是相对低级的程序设计语言,相当于汇编语言。LD,SFC,FBD ,CFC 都是图形化编程方法,而ST 是基于文本型编程语言。

在上述6 种编程方式中,ST和CFC 在支持OOIP 方面做出了努力。 

ST 对OOIP的支持

IEC61131-3 的2012 (第三版)中增加了对面向目标程序设计的内容,主要包括了INTERFACE ,METHOD,IMPLEMENTS 等等。

     ST 对OOP 的支持包括

     功能(function)

     功能块(function block)

     程序(program)

功能(Function)是包含局部变量和指令的代码,可以设置输入/输出参数。功能没有静态变量,因此每次调用都会产生同一个结果;功能与通用程序设计程序语言(例如C)的函数非常类似

实例:功能

FUNCTION SIMPLE_FUN : REAL
VAR_INPUT
A, B : REAL;
C : REAL := 1.0;
END_VAR
SIMPLE_FUN := A*B/C;
END FUNCTION

    功能块:

     功能块(Function Block)与功能的区别在于它有属于自己的存储区,可以存放静态变量。功能块也可以设置输入/输出参数,但由于程序代码中静态变量可能发生变化,因此对于功能块的调用并不一定产生同样的结果。

(* Rising edge detector *)
Function_Block R_TRIG
	Var_Input CLK : Bool; End_Var
	Var_Output Q : Bool; End_Var
	Var M : Bool := False; End_Var

	Q := CLK AND NOT M;
	M := CLK;
End_Function_Block

 功能块的扩展

IEC61131-3 的2012 (第三版)中增加了对面向目标程序设计的内容,主要包括了INTERFACE ,METHOD,IMPLEMENTS 等等。

    接口

接口类似于C++ 的 .h 文件。它不包括method 的实现。

INTERFACE ROOM
METHOD DAYTIME:VOID
END METHOD
METHOD NIGHTTIME :VOID
END_METHOD
END_INTERFACE

 实现

FUNCTION BLOCK LIGHTROOM IMPLWMENTS ROOM
VAR LIGHTlBOOL;
END_VAR
PUBLIC MWTHOD DATTIME:VOID
LIGHT:FALSE;
END_METHOD
PUBLIC METHOD NIGHTTIME :VOID
LIGHT:=TRUE;
END_METHOD
END_FUNCYION_BLOCK

 继承

FUNCTION_BLOCK LIGHT2ROOM EXTENDS LIGHTROOM
VAR
   LIGHT2:BOOL;
END_VAR
PUBLIC METHOD DAYTIME:VOID
SUPER.DAYTIME();
LIGHT2:=FALSE;
END_METHOD
PUBLIC METHOD NIGHTTIME:VOID
SUPER.NIGHTTIME();
LIGHT2:=TRUE;
END_METHOD
END_FUNCTION_BLOCK

引用方式

 

FUNCTION_BLOCK ROOM_CTRL
VAR_INPUT
RM:ROOM;
END_VAR
VAR_EXTERNAL
  DAYTIME:TOD
END_VAR
IF (RM=NUMM) THEN
RETURN;
END_IF
IF DAYTIME>=TOD#20:15 OR DAYTIME <=TOD#6:00 THEN
    RM.NIGHTTIME()
ELSE
    RM.DAYTIME();
END_IF
END_FUNCTION_BLOCK

     CFC 对OOIP 的支持

             从上面我们已经看到,ST语言已经具备OOP 的能力了。只是好像周边的控制工程师并不使用这些OOP机制。控制工程师更倾向使用图形化编程方法。CFC 就是这样一种图形编程方法。

CFC是FBD的超集,具有两个优势:

  1. 基于块的功能编程(执行布尔和数学运算)
  2. 分层设计(调用其他功能和功能块)
  3. 基于图形化编程。

 CFC 最大的优点就是能够实现分层设计,你可以使用已有的功能块构建新的功能块。实现了类似OPP 中类的继承和实例化。我们可以通过一个例子来说明CFC 的设计方法。

在codesys 的CFC编辑器中,拖放基本的功能块,然后连线和标注信好名称。构建块网络。CFC 功能块网络是典型的数据流编程方式。这种数据流网络是基于数据流执行的,有时候难以确定功能块的执行顺序。在CFC 网络中,每个功能块的右上方有一个数字,表示了功能块的执行顺序。用户可以通过编辑器改变功能块的执行顺序。

基于IEC61499 的OOIP

       IEC61499 是基于事件功能块的分布式工业控制系统的标准。有人说IEC61499 是IEC61131-3 的后继者。我并不同意这种说法,但是它吸取了IEC61131-3 发展过程中的成果,弥补了IEC61131-3 的不足。毕竟设计一个全新的标准要比扩展一个标准容易,没有兼容性的包袱。

IEC61499 的分布式模型

   1 基于事件的功能块,当某个事件到来时通过内部状态机(ECC)来确定内部状态的变化,并且根据当前状态来决定执行哪一个内部方法(algrithem),从而使得功能块网络的执行顺序是确定的,不再需要向CFC那样规定执行的顺序。

  2 提供了复合功能块和子应用的概念,实现了在功能块中调用其它的功能块。实现了模块化和分层设计能力。子应用和复合功能块的主要区别在于子应用的执行可以分布式的,也就是说,子应用中的某些功能块在一个设备的资源上运行,而另一部分在另一个设备的资源中运行。而复合功能块智能在同一个设备上运行。

3 功能块网络完全可以基于图形化设计,而内部算法可以使用ST 语言或者其它程序设计语言来编写。

4 功能块库能够实现重复使用和分享。

5 功能块实例化类似于OOP 中类(class)的实例化。

控制系统的分层架构

   到现在为止,我们已经看到,无论是IEC61131-3,还是IEC61499 都已经实现了对OOIP 的支持。不过,控制工程师还并没有普遍地使用OOP 理念来构建控制程序。其实对于构建大型的控制系统时,学习一些OOP 理念和技术,会带来事半功倍的效果。在设计过程中,首先要吸取信息技术领域分层架构的思想,自顶向下地设计控制系统。

     分层架构实现了模块化设计,为多人编写控制程序提供了可能性。实际上,我们普遍看到的是控制系统软件是一个工程师编写的。 当复杂软件变的庞大,并且需要不同知识背景的工程师来实现。

       分层架构的第二个目的是将控制逻辑和硬件控制分离。将控制系统的功能块分为平台独立的模型Platform Independent Model (PIM),和平台依赖的模型(Platform Specific Model (PSM))。平台独立的模型是能够重用的,而且与厂商无关。而PSM 模型是厂商依赖的。我们回顾PLC的梯形图,它的逻辑模型和硬件控制完全是交织在一起的。所以很难地实现重用(reuse)。

在上图中,lavyer1 是基于硬件的。而layer 2和layer 3 实现与硬件的解耦。也有人研究在GA和GD 之间增加适配层,让控制程序能方便地移植到不同厂商的硬件平台上。

       下图是IEC61499 的分层架构,既可以使用复合功能块来构建,也可以使用子应用来构建,Level 2 的子应用、功能块中包含了level 3 的子应用/功能块。Level 1 的子应用、功能块中包含了level 2 的子应用/功能块。使用子应用或者复合功能块的嵌套实现分层。

 

结束语

  在介绍IEC61131-3 或者IEC61499 的应用例子中都是一些小的应用实例。在实际应用中,控制程序还是复杂的和庞大的。图形化控制程序设计给控制工程师带来了便捷,但是由于图形化程序的信息密度低(用大白话来讲,就是一个屏幕上画不了多少功能块及其连线。分层设计能够使控制逻辑分解成更加清晰的模块。分层架构实现控制逻辑和硬件控制功能块分离,实现与厂商无关和重复使用。

分层设计和面向对象程序设计在控制领域并不普及,但是学习一些这方面的理念和技巧,对控制工程师是有帮助的。

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值