PRISM概率模型检测器初使用(2)--嵌入式控制系统模型



PRISM—probabilistic model checker概率模型检测器

嵌入式控制系统模型 Theembedded control system 

http://www.prismmodelchecker.org/casestudies/embedded.php  与连续时间马尔科夫链有关


 

模型说明

系统说明:

1.系统包含一个输入处理器inputprocessorI),可读取和处理来自三个传感器sensorS1S2S3)的数据

2.一个主处理器main processorM)读取来自I的数据并把指令传给O;记录处理时间周期长度的计时器timerM

3.一个输出处理器outputprocessorO),接受收到的指令并由此控制两个驱动器actuatorA1A2

4.一个总线bus连接三个处理器(I,M,O

 

停机(shut down)条件:

  1. 超过一个传感器S失效,即S的数量<2,系统停机----MIN_SENSORS=2;

  2. 两个驱动器A都失效,即A的数量<1,系统停机----MIN_ACTUATORS=1;

  3. 输入/输出处理器也会失效,可能是永久性故障(permanentfault)或暂时性故障(transientfault):

    如果系统暂时性故障,它自己可以自动改正并重新启动(reboot),也就是说暂时性故障的后一状态可能是重启(几率为1/30;

    如果是永久性,那么I/O处理器不能运作导致主处理器不能读取和输出,那么M会强力直接跳过这个周期,如果M跳过的连续周期数量超过限制,系统会停机----MAX_COUNT

  4. 除非特殊规定,我们假设MAX_COUNT=2

  5. 主处理器M也可以失效,系统也就自动死机了

 

平均失效发生次数(概率)rate

一个传感器S sensor1 month ---- lambda_s = 1/(30*24*60*60);

一个驱动器A actuator 2 month ---- lambda_a = 1/(2*30*24*60*60);

一个处理器(I,M,Oprocessor1 year ---- lambda_p = 1/(365*24*60*60)

一个暂时性故障transient fault1day ---- delta_f = 1/(24*60*60);

一个计时器周期timer cycle1minute ----tau= 1/60;

一个处理器重启时间processor reboot30seconds ----delta_r = 1/30;

(假设这些延期时间呈指数分布,所以这个系统可以用连续时间马尔科夫链CTMC建模)

 

PRISM code

ctmc

 

//constants

constint MAX_COUNT;

constint MIN_SENSORS =2;

constint MIN_ACTUATORS =1;

 

//rates

constdouble lambda_p =1/(365*24*60*60);// 1 year

constdouble lambda_s =1/(30*24*60*60);// 1 month

constdouble lambda_a =1/(2*30*24*60*60);// 2 months

constdouble tau =1/60;// 1 min

constdouble delta_f =1/(24*60*60);// 1 day

constdouble delta_r =1/30;// 30 secs

 

//sensors

modulesensors

      

      s : [0..3]init 3;// number of sensorsworking

      

      [] s>1 -> s*lambda_s : (s'=s-1);// failure of a singlesensor

      

endmodule

 

//input processor

//(takes data from sensors and passes onto main processor)

moduleproci

      

      i : [0..2]init 2;// 2=ok, 1=transientfault, 0=failed

      

      [] i>0 & s>=MIN_SENSORS -> lambda_p : (i'=0);// failure ofprocessor

      [] i=2 & s>=MIN_SENSORS -> delta_f : (i'=1);// transient fault

      [input_reboot]i=1 & s>=MIN_SENSORS -> delta_r : (i'=2);// reboot aftertransient fault

      

endmodule

 

//actuators

moduleactuators

      

      a : [0..2]init 2;// number of actuatorsworking

      

      [] a>0 -> a*lambda_a : (a'=a-1);// failure of a singleactuator

      

endmodule

 

//output processor

//(receives instructions from main processor and passes onto actuators)

moduleproco =proci [i=o,s=a,input_reboot=output_reboot,MIN_SENSORS=MIN_ACTUATORS ] endmodule

 

//main processor

//(takes data from proci, processes it, and passes instructions to proco)

moduleprocm

      

      m : [0..1]init 1;// 1=ok, 0=failed

      count : [0..MAX_COUNT+1]init 0;// number ofconsecutive skipped cycles

      

      //failure of processor

      [] m=1 -> lambda_p : (m'=0);

      //processing completed before timer expires - reset skipped cycle counter

      [timeout] comp ->tau : (count'=0);

      //processing not completed before timer expires - increment skipped cycle counter

      [timeout] !comp -> tau : (count'=min(count+1,MAX_COUNT+1));

      

endmodule

 

//connecting bus

modulebus

      

      //flags

      //main processor has processed data from input processor

      //and sent corresponding instructions to output processor (since last timeout)

      comp :bool init true;

      //input processor has data ready to send

      reqi :bool init true;

      //output processor has instructions ready to be processed

      reqo :bool init false;

      

      //input processor reboots

      [input_reboot] true -> 1 :

      //performs a computation if has already done so or

      //it is up and ouput clear (i.e. nothing waiting)

      (comp'=(comp | (m=1 & !reqo)))

      //up therefore something to process

      & (reqi'=true)

      //something to process if not functioning and either

      //there is something already pending

      //or the main processor sends a request

      & (reqo'=!(o=2 & a>=1) & (reqo |m=1));

      

      //output processor reboots

      [output_reboot]true -> 1 :

      //performs a computation if it has already or

      //something waiting and is up

      //(can be processes as the output has come up and cleared pending requests)

      (comp'=(comp | (reqi &m=1)))

      //something to process it they are up or

      //there was already something and the main processor acts

      //(output now up must be due to main processor being down)

      & (reqi'=(i=2 & s>=2) | (reqi &m=0))

      //output and actuators up therefore nothing can be pending

      & (reqo'=false);

      

      //main processor times out

      [timeout]true -> 1 :

      //performs a computation if it is up something was pending

      //and nothing is waiting for the output

      (comp'=(reqi & !reqo &m=1))

      //something to process if up or

      //already something and main process cannot act

      //(down or outputs pending)

      & (reqi'=(i=2 & s>=2) | (reqi & (reqo | m=0)))

      //something to process if they are not functioning and

      //either something is already pending

      //or the main processor acts

      & (reqo'=!(o=2 & a>=1) & (reqo | (reqi & m=1)));

      

endmodule

 

//the system is down

formuladown = (i=2&s<MIN_SENSORS)|(count=MAX_COUNT+1)|(o=2&a<MIN_ACTUATORS)|(m=0);

//transient failure has occured but the system is not down

formuladanger = !down & (i=1 | o=1);

//the system is operational

formulaup = !down & !danger;

 

//reward structures

 

rewards "up"

      up :1/3600;

endrewards

rewards "danger"

      danger :1/3600;

endrewards

rewards "down"

      down :1/3600;

endrewards

 

代码解释:

• []s>1 ->s*lambda_s : (s'=s-1);   左边是执行下一状态的概率,右边是下一状态。这里指当s>1时,执行s’=s-1的概率为s*lambda_s。如s3时,执行s=2的概率为3*lambda_s.


module proco = proci [ i=o,s=a,input_reboot=output_reboot,MIN_SENSORS=MIN_ACTUATORS ]endmodule 即把上个模型proci的变量套用到这里。


i: [0..2]init2; // 2=ok,1=transient fault,0=failed状态2正常运行,1暂时失效,0死机。

[]i=2 &s>=MIN_SENSORS ->delta_f: (i'=1);I,S没问题时,有暂时失效的可能性跳到i=1

[input_reboot]i=1 &s>=MIN_SENSORS->delta_r : (i'=2);在暂时失效状态时有重启可能回到状态t=2,即OK。该动作叫input_reboot,在模块proci内。(动作:可使不同模块间的不同状态(在同一动作内)同时发生,具体参考同时性synchronisationhttp://www.prismmodelchecker.org/manual/ThePRISMLanguage/Synchronisation


count: [0..MAX_COUNT+1]init 0;count记录连续跳跃周期的数目,初始值为0.

[timeout] comp ->tau : (count'=0);设置timeout动作,当处于comp状态时(后面有说明是主处理器M的上一状态是正常的),有tau的可能性,进程在一个时间周期内完成,跳跃就不连续了,重设count=0.

[timeout] !comp ->tau: (count'=min(count+1,MAX_COUNT+1)); 设置timeout动作,当处于非comp状态时(即主处理器M的上一状态是不正常的),有tau的可能性,进程没能在一个时间周期内完成,跳跃就连续了,count就加1.


• [input_reboot] true -> 1: (comp'=(comp| (m=1& !reqo))) & (reqi'=true) & (reqo'=!(o=2 &a>=1) &(reqo |m=1));(该动作与上面的在不同的模块,该动作在bus模块内,两处同时发生)

proci模块中的input_reboot动作发生时,bus模块里的input_reboot动作百分之一百(true)执行,概率为1(百分之一百)执行下一状态comp’reqi‘reqo’

comp’状态执行时,M输入输出正常(comp,或者M正常时O不正常(m=1 & !reqo)

reqi’I百分之百正常(reqi'=true)

reqo’O可正常也可不正常& (reqo'=!(o=2 &a>=1) &(reqo |m=1)

这里的括号要注意!!


代码用法具体网址:http://www.prismmodelchecker.org/manual/ThePRISMLanguage/Commands

http://www.prismmodelchecker.org/manual/ThePRISMLanguage/ModulesAndVariables

http://www.prismmodelchecker.org/manual/ThePRISMLanguage/Synchronisation


测试1

我用模拟器simulator玩了一下这个系统,在步骤steps里填入1000100001000001000000分别测试,发现10000是比较好的步骤测试数。下图就是两次10000步的运行下系统死机的情况:

可以看出这次系统死机是因为两个传感器都挂了(S<2)所以系统直接死机了,在‘down’一栏不为0了。当然这次测试的步骤中间系统还是进行过多次自救的(reboot),如下图。仔细看Rewards中的‘up’‘danger’栏,O暂时失效了。

 

测试2

我用PRISM给的属性测了一下概率分布图,属性的源代码地址:

http://www.prismmodelchecker.org/casestudies/examples/embedded.csl

  1. 第一个测试的属性是P=? [ !"down" U<=T"fail_j" ]

     

    这里的down即是死机,插入源代码后down标签已设置好,不用自己设。

    “fail_j”j=1..4,标签"fail_1"意义为"s<2 & i=2",对应代码中的fail_sensors

    标签"fail_2"意义为"a<1 &o=2 ",对应代码中的fail_actuators

    标签"fail_3"意义为"COUNT=MAX_COUNT+1",对应代码中的fail_io

    标签"fail_4"意义为"m=0",对应代码中的fail_main

    所以这个测试不需要自己写属性,只要把标签中的一些意义稍微改动即可。注意,在生成新试验图时,MAX_COUNT的范围range选择前面的startT设为后面的end并赋值0-24(图一时间长是24小时且T=1h,图二是30天且T=1d要填0-30step1

    图一用的属性是P=? [!"down" U<=T*3600 "fail_main" ]等等(共四个属性),T被乘了3600说明T单位为1h(小时)。

    图二用的属性是P=? [!"down" U<=T*3600*24 "fail_sensors" ]等等(共四个),T被乘以3600*24,说明T单位为1d(天)。

     

    24小时:第一张是PRISM给的结果图,第二张是我测的图


  2. 结果看来还是有一些差距的,我的图中M的线和S靠得很近被盖住了,但放大看其实和给的图走向差不多,唯一的区别就是I/O线。我一开始有点迷茫为什么差距这么大,直到我调了MAX_COUNT的参数。我之前设它的range点击start并给值0,也就是说不允许M连续跳跃I/O的失效。我把值分别改成12,对应的是下面的I/O线和I/O2)线。

    果然,I/O2)线的结果和PRISM给的结果相似,所以PRISM测试时count的值设的是2,而我设的是0,至于我的图中别的线没有受影响也是因为count对应的连续跳跃超限只给I/O死机带来影响。

     

    1个月T30。一个月的图确实每个曲线都要跑十几分钟才出来。第一张PRISM的,第二张我的。别问我为什么只有S。。跑太久了,你们要跑自己跑吧。。后面还有测试呢,实际上测试结果都和PRISM给的图差不多,可以自己改动参数玩玩。


     

  3. 第二个测的属性是P=? [ !"down" U "fail_j"]

    这里的j也是1..4,对应的也和上面一样。右键单击属性,用“Verify”测试。

    测试时count也是用2PRISM给出的结果如左下,右下是sensor的结果:

Failure type

 

Probability

Sensors

0.6214

Actuators

0.0877

I/O processors

0.2425

Main processor

0.0484

结果都是一样的,另外三个我也测了都一样,就不列出来了。

有意思的是,当我把count改成1时,可能性也跟着变了(0也不一样):

我倒回去再试了一次上一属性sensorcount分别为012时,曲线几乎的盖在一起,说明上一属性确实没问题。那么这里的sensor的可能性为什么就会受count影响呢?

嗯我仔细想了想,我个人觉得应该和这个属性的设置有关,这个属性里只有“U”没有“T”,也就没有时间这个变量了。所以能够影响属性的就只有恒量count,而count因为我设置的不同,就产生了不同的结果。(具体内部是怎么计算的我目前还没搞懂。。)

测试3

  1. R{"reward_structure"}=? [C<=T ] 这个R指的是total cumulatedreward,也就是总共积累的rewardreward_structure对应有三个标签"down","danger""up"

    同样绘制两幅图,第一副24h,第二幅30dcount先默认设2看看。下面是PRISM跑出来的图。

值得注意的是,这里count恒量的改动是会引起reward变化的,PRISM也给出了变化的结果:

 

MAX_COUNT:

 

Expected time:

danger (hrs):

up (days):

1

0.236

14.323

2

0.293

17.660

3

0.318

19.100

4

0.327

19.628

5

0.330

19.809

6

0.331

19.871

7

0.332

19.891

                               

                     

 

 

 

 

1.最后一个R{"reward_structure"}=? [ F "down" ]的步骤也都类似。


posted @ 2016-03-13 22:34  sriting  阅读(770)  评论(0编辑  收藏  举报