zoukankan      html  css  js  c++  java
  • 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" ]的步骤也都类似。


  • 相关阅读:
    NFS服务简单配置
    TCP/IP网络
    python文件问题
    明明apple id 密码 是对的,登陆 iTunes还总提示密码错误
    台式电脑怎么使用iPhone热点进行上网
    Svn总是提示输入账号密码
    unity的相关技巧
    正则表达式标记
    NGUI用UIGrid加载Item会有部分空出来的解决办法
    win10 硬盘占用率经常100%的可能有用的解决方案
  • 原文地址:https://www.cnblogs.com/sriting/p/6031987.html
Copyright © 2011-2022 走看看