『7x24小时有问必答』
以下是修改的新版界面,已经根据不同的dcs,把算法和积分增益的单位做了相应的改变。
用法:
把以下的所有代码拷贝到一个txt文本文件中,保存以后,把文件名改成html后缀,直接用Edge浏览器运行即可。

       <meta charset="UTF-8">

       <meta http-equiv="X-UA-Compatible" content="IE=edge">

       <title>专业DCS-PID仿真系统</title>

       <style>

               body { font-family: "SimHei", "Microsoft YaHei", sans-serif; margin: 0; padding: 8px; background: #e0e0e0; font-size: 12px; }

               .container { max-width: 1350px; margin: 0 auto; background: white; padding: 12px; border: 2px solid #333; box-shadow: 0 0 10px rgba(0,0,0,0.3); }

               h1 { text-align: center; font-size: 20px; margin-bottom: 10px; color: #000; background: #b0c4de; padding: 8px; border: 1px solid #333; }

               .main { display: flex; gap: 12px; }

               .left { width: 400px; min-width: 400px; }

               .right { flex: 1; border: 2px solid #333; background: #f5f5f5; position: relative; }

               .panel { border: 1px solid #666; margin-bottom: 8px; background: #fafafa; }

               .panel-title { font-weight: bold; background: #d3d3d3; padding: 6px; border-bottom: 1px solid #666; font-size: 13px; color: #000; }

               .panel-body { padding: 8px; }

               .row { margin-bottom: 6px; display: flex; align-items: center; min-height: 28px; }

               .row label { width: 130px; font-size: 11px; font-weight: bold; color: #333; }

               .unit-label { font-size: 10px; color: #666; margin-left: 3px; font-weight: normal; }

               input[type="range"] { width: 120px; vertical-align: middle; }

               input[type="number"] { width: 60px; padding: 3px; border: 1px solid #666; }

               select { width: 180px; padding: 3px; border: 1px solid #666; font-size: 11px; }

               .val { display: inline-block; width: 45px; text-align: center; background: #fffacd; border: 1px solid #999; margin-left: 5px; font-size: 11px; color: #c00; font-weight: bold; font-family: monospace; }

               .hidden { display: none !important; }

               button { padding: 8px 18px; margin: 4px; cursor: pointer; font-weight: bold; font-size: 12px; border: 2px solid #333; }

               #btnStart { background: #32cd32; }

               #btnPause { background: #ffd700; }

               #btnReset { background: #ff6347; color: white; }

               button:disabled { opacity: 0.5; cursor: not-allowed; }

               canvas { display: block; width: 100%; height: 500px; background: white; }

               .legend { text-align: center; margin: 8px 0; font-size: 12px; font-weight: bold; background: #e0e0e0; padding: 5px; border-top: 1px solid #666; }

               .legend span { margin: 0 20px; }

               .status { padding: 8px; background: #f0f0f0; border-top: 2px solid #333; font-family: "Courier New", monospace; font-size: 13px; font-weight: bold; text-align: center; }

               .dcs-info { background: #e6f3ff; border: 1px solid #0066cc; padding: 6px; margin-bottom: 8px; font-size: 11px; color: #004080; }

               .algo-desc { font-size: 10px; color: #666; margin-top: 2px; font-style: italic; }

               .warning { color: #ff6600; font-size: 10px; margin-left: 5px; }

       </style>

       <div>

               <h1>多DCS-PID控制回路仿真系统 (工业级算法)</h1>

               

               <div>

                       <div>

                               <div>

                                       <div>1. DCS系统选择 (决定算法与单位)</div>

                                       <div>

                                               <div>

                                                       <label>选择DCS类型:</label>

                                                       <select onchange="changeDCS()">

                                                               <option value="isa">ISA标准 (理想型)</option>

                                                               <option value="emerson">艾默生 DeltaV (非交互式)</option>

                                                               <option value="honeywell">霍尼韦尔 TDC3000 (比例度%)</option>

                                                               <option value="yokogawa">横河 CENTUM (微分先行)</option>

                                                               <option value="siemens">西门子 PCS7 (并行算法)</option>

                                                               <option value="hollysys">和利时 MACS (理想型)</option>

                                                               <option value="supcon">中控 ECS (理想型)</option>

                                                       </select>

                                               </div>

                                               <div>

                                                       <strong>当前算法:</strong>位置式PID,标准ISA形式<br>

                                                       <strong>单位:</strong>Kp(无量纲增益), Ti(秒), Td(秒)<br>

                                                       <strong>公式:</strong>MV = Kp×[e + (1/Ti)∫e + Td×de/dt]

                                               </div>

                                       </div>

                               </div>

                              

                               <div>

                                       <div>2. 被控对象模型</div>

                                       <div>

                                               <div>

                                                       <label>对象类型:</label>

                                                       <select onchange="changeObj()">

                                                               <option value="fopdt">一阶惯性+纯滞后</option>

                                                               <option value="int">纯积分(液位)</option>

                                                               <option value="sopdt">二阶惯性+纯滞后</option>

                                                       </select>

                                               </div>

                                               

                                               <div>

                                                       <div>

                                                               <label>增益 K:</label>

                                                               <input type="range" min="0.1" max="10" step="0.1" value="1.5" oninput="updateVal('k','v-k')">

                                                               <span>1.5</span>

                                                       </div>

                                                       <div>

                                                               <label>时间常数 τ:</label>

                                                               <input type="range" min="1" max="100" step="1" value="20" oninput="updateVal('tau','v-tau')">

                                                               <span>20</span>

                                                               <span>秒</span>

                                                       </div>

                                                       <div>

                                                               <label>滞后时间 θ:</label>

                                                               <input type="range" min="0" max="30" step="0.5" value="3" oninput="updateVal('theta','v-theta')">

                                                               <span>3</span>

                                                               <span>秒</span>

                                                       </div>

                                               </div>

                                               

                                               <div>

                                                       <div>

                                                               <label>积分增益 K:</label>

                                                               <input type="range" min="0.01" max="1" step="0.01" value="0.05" oninput="updateVal('ki','v-ki')">

                                                               <span>0.05</span>

                                                       </div>

                                               </div>

                                               

                                               <div>

                                                       <div>

                                                               <label>增益 K:</label>

                                                               <input type="range" min="0.1" max="10" step="0.1" value="1" oninput="updateVal('k2','v-k2')">

                                                               <span>1.0</span>

                                                       </div>

                                                       <div>

                                                               <label>滞后 θ:</label>

                                                               <input type="range" min="0" max="30" step="0.5" value="2" oninput="updateVal('t2','v-t2')">

                                                               <span>2</span>

                                                       </div>

                                                       <div>

                                                               <label>时间常数1 τ1:</label>

                                                               <input type="range" min="1" max="50" step="1" value="8" oninput="updateVal('tau1','v-t1')">

                                                               <span>8</span>

                                                       </div>

                                                       <div>

                                                               <label>时间常数2 τ2:</label>

                                                               <input type="range" min="1" max="50" step="1" value="12" oninput="updateVal('tau2','v-t2')">

                                                               <span>12</span>

                                                       </div>

                                               </div>

                                       </div>

                               </div>

                              

                               <div>

                                       <div>3. PID参数整定 (随DCS类型自动切换单位)</div>

                                       <div>

                                               <div>

                                                       <label>比例增益 Kp:</label>

                                                       <input type="range" min="0.1" max="100" step="0.1" value="2" oninput="updateVal('pVal','v-p')">

                                                       <span>2.0</span>

                                                       <span>无量纲</span>

                                               </div>

                                               <div>

                                                       <label>积分时间 Ti:</label>

                                                       <input type="range" min="1" max="100" step="1" value="30" oninput="updateVal('iVal','v-i')">

                                                       <span>30</span>

                                                       <span>秒</span>

                                                       <select onchange="changeDCS()">

                                                               <option value="sec">秒</option>

                                                               <option value="min">分</option>

                                                       </select>

                                               </div>

                                               <div>

                                                       <label>微分时间 Td:</label>

                                                       <input type="range" min="0" max="20" step="0.5" value="0" oninput="updateVal('dVal','v-d')">

                                                       <span>0</span>

                                                       <span>秒</span>

                                               </div>

                                               <div>

                                                       <label>设定值 SP:</label>

                                                       <input type="number" value="50" min="0" max="100">

                                                       <span>%</span>

                                               </div>

                                               <div></div>

                                       </div>

                               </div>

                              

                               <div>

                                       <div>4. 干扰设置</div>

                                       <div>

                                               <div>

                                                       <label>干扰类型:</label>

                                                       <select onchange="changeDist()">

                                                               <option value="none">无干扰</option>

                                                               <option value="step">阶跃干扰</option>

                                                               <option value="sine">正弦干扰</option>

                                                               <option value="square">方波干扰</option>

                                                       </select>

                                               </div>

                                               <div>

                                                       <div>

                                                               <label>干扰幅度:</label>

                                                               <input type="number" value="10">

                                                               <span>%</span>

                                                       </div>

                                                       <div>

                                                               <label>施加时间:</label>

                                                               <input type="number" value="60">

                                                               <span>秒</span>

                                                       </div>

                                                       <div>

                                                               <label>周期:</label>

                                                               <input type="range" min="5" max="100" value="30" oninput="updateVal('dPer','v-per')">

                                                               <span>30</span>

                                                               <span>秒</span>

                                                       </div>

                                               </div>

                                       </div>

                               </div>

                              

                               <div>

                                       <div>5. 仿真设置</div>

                                       <div>

                                               <div>

                                                       <label>仿真速度:</label>

                                                       <select>

                                                               <option value="0.2">慢速(0.2x)</option>

                                                               <option value="0.5" selected="">中速(0.5x)</option>

                                                               <option value="1">正常(1x)</option>

                                                               <option value="2">快速(2x)</option>

                                                       </select>

                                               </div>

                                               <div>

                                                       <label>总时长:</label>

                                                       <input type="number" value="200" min="50" max="500" step="10">

                                                       <span>秒</span>

                                               </div>

                                       </div>

                               </div>

                              

                               <div>

                                       <button onclick="startSim()">开始仿真</button>

                                       <button onclick="pauseSim()">暂停</button>

                                       <button onclick="resetSim()">重置系统</button>

                               </div>

                       </div>

                       

                       <div>

                               <canvas width="850" height="500"></canvas>

                               <div>

                                       <span>— PV(过程值)</span>

                                       <span>— SP(设定值)</span>

                                       <span>— MV(阀位输出)</span>

                               </div>

                               <div>

                                       <span>就绪</span> |

                                       时间: <span>0.0</span>s |

                                       PV: <span>0.00</span>% |

                                       MV: <span>0.00</span>% |

                                       偏差: <span>0.00</span>%

                               </div>

                       </div>

               </div>

       </div>

<script>

var cv, cx, tm=null, run=false, pausef=false, ct=0, lmv=0, lerr=0;

var dt={t:[],pv:[],sp:[],mv:[]};

var ps={y:0,y1:0,i:0,le:0,lpv:0,db:[]};

var DCS_CONFIG = {

       isa: {

               name: "ISA标准",

               pName: "比例增益 Kp",

               pUnit: "无量纲",

               iName: "积分时间 Ti",

               iUnit: "sec",

               dName: "微分时间 Td",

               dUnit: "秒",

               algo: "ideal",

               desc: "位置式PID,标准形式: MV = Kp×[e + (1/Ti)∫e·dt + Td×de/dt]",

               note: "Ti越大积分作用越弱,经典教科书算法"

       },

       emerson: {

               name: "艾默生 DeltaV",

               pName: "比例增益 K",

               pUnit: "无量纲",

               iName: "复位时间 Reset",

               iUnit: "sec",

               dName: "速率时间 Rate",

               dUnit: "秒",

               algo: "noninteractive",

               desc: "非交互式算法: 比例、积分、微分独立计算后叠加",

               note: "三种作用互不干扰,现代DCS常用"

       },

       honeywell: {

               name: "霍尼韦尔 TDC3000",

               pName: "比例度 PB",

               pUnit: "%",

               iName: "积分时间",

               iUnit: "min",

               dName: "微分时间",

               dUnit: "分",

               algo: "pb",

               desc: "PB=100/Kp,Ti单位为分(重复/分),传统仪表习惯",

               note: "PB越小控制作用越强!Ti越小积分越快!"

       },

       yokogawa: {

               name: "横河 CENTUM",

               pName: "比例带 P",

               pUnit: "%",

               iName: "积分时间 I",

               iUnit: "sec",

               dName: "微分时间 D",

               dUnit: "秒",

               algo: "derivative_first",

               desc: "PI-D算法: 微分仅作用于测量值,设定值变化无冲击",

               note: "SV突变时MV无跳变,适合频繁改设定值的场合"

       },

       siemens: {

               name: "西门子 PCS7",

               pName: "增益 Gain",

               pUnit: "无量纲",

               iName: "积分时间 Ti",

               iUnit: "sec",

               dName: "微分时间 Td",

               dUnit: "秒",

               algo: "parallel",

               desc: "并行算法: P,I,D分别计算: MV = Kp×e + (Kp/Ti)∫e + Kp×Td×de/dt",

               note: "与ISA数学等价,但参数整定思路不同"

       },

       hollysys: {

               name: "和利时 MACS",

               pName: "比例系数 Kp",

               pUnit: "无量纲",

               iName: "积分时间 Ti",

               iUnit: "sec",

               dName: "微分时间 Td",

               dUnit: "秒",

               algo: "ideal",

               desc: "国产DCS,采用ISA标准算法",

               note: "与ISA算法完全一致"

       },

       supcon: {

               name: "中控 ECS",

               pName: "比例增益",

               pUnit: "无量纲",

               iName: "积分时间",

               iUnit: "sec",

               dName: "微分时间",

               dUnit: "秒",

               algo: "ideal",

               desc: "国产DCS,采用ISA标准算法",

               note: "与ISA算法完全一致"

       }

};

window.onload=function(){

       cv=document.getElementById('trendCanvas');

       cx=cv.getContext('2d');

       resize();

       window.onresize=resize;

       changeDCS();

       drawChart();

};

function resize(){

       var r=cv.parentNode.getBoundingClientRect();

       cv.width=r.width-4;

       cv.height=500;

}

function updateVal(id,vid){

       document.getElementById(vid).innerHTML=document.getElementById(id).value;

}

function changeDCS(){

       var type=document.getElementById('dcsType').value;

       var cfg=DCS_CONFIG[type];

      

       document.getElementById('lblP').innerHTML=cfg.pName+":";

       document.getElementById('unitP').innerHTML=cfg.pUnit;

       document.getElementById('lblI').innerHTML=cfg.iName+":";

       document.getElementById('lblD').innerHTML=cfg.dName+":";

       document.getElementById('unitD').innerHTML=cfg.dUnit;

      

       var iUnitSelect=document.getElementById('iUnit');

       if(cfg.iUnit==='min'){

               iUnitSelect.value='min';

               iUnitSelect.disabled=true;

               document.getElementById('unitI').innerHTML='分';

               document.getElementById('iVal').max=30;

               document.getElementById('iVal').step=0.1;

       }else{

               iUnitSelect.disabled=false;

               document.getElementById('unitI').innerHTML=iUnitSelect.value==='min'?'分':'秒';

               document.getElementById('iVal').max=100;

               document.getElementById('iVal').step=1;

       }

      

       document.getElementById('dcsDesc').innerHTML=

               '<strong>当前算法:</strong>'+cfg.desc+'<br>'+

               '<strong>单位:</strong>'+cfg.pName.split(' ')[0]+'('+(cfg.pUnit==='%'?'比例度':'增益')+'), '+cfg.iName+(cfg.iUnit==='min'?'(分)':'(秒)')+'<br>'+

               '<strong>注意:</strong>'+cfg.note;

       document.getElementById('algoNote').innerHTML='算法特性: '+cfg.note;

      

       if(cfg.algo==='pb'){

               document.getElementById('pVal').min=1;

               document.getElementById('pVal').max=500;

               document.getElementById('pVal').step=1;

               if(parseFloat(document.getElementById('pVal').value)<1){

                       document.getElementById('pVal').value=50;

                       updateVal('pVal','v-p');

               }

       }else{

               document.getElementById('pVal').min=0.1;

               document.getElementById('pVal').max=20;

               document.getElementById('pVal').step=0.1;

       }

}

function changeObj(){

       var t=document.getElementById('objType').value;

       document.getElementById('par-fopdt').className='hidden';

       document.getElementById('par-int').className='hidden';

       document.getElementById('par-sopdt').className='hidden';

       document.getElementById('par-'+t).className='';

}

function changeDist(){

       var t=document.getElementById('distType').value;

       var p=document.getElementById('dist-par');

       var tr=document.getElementById('d-time-row');

       var pr=document.getElementById('d-period-row');

       if(t=='none'){p.className='hidden';}

       else{

               p.className='';

               if(t=='step'){tr.className='row';pr.className='row hidden';}

               else{tr.className='row hidden';pr.className='row';}

       }

}

function getDist(t){

       var ty=document.getElementById('distType').value;

       var a=parseFloat(document.getElementById('dAmp').value)||0;

       if(ty=='none')return 0;

       if(ty=='step'){

               var st=parseFloat(document.getElementById('dTime').value)||0;

               return t>=st?a:0;

       }

       if(ty=='sine'){

               var p=parseFloat(document.getElementById('dPer').value)||20;

               return a*Math.sin(6.283185*t/p);

       }

       if(ty=='square'){

               var p=parseFloat(document.getElementById('dPer').value)||20;

               return ((t%p)<(p/2))?a:-a;

       }

       return 0;

}

function calcPID(sp,pv,dt){

       var dcsType=document.getElementById('dcsType').value;

       var cfg=DCS_CONFIG[dcsType];

      

       var pRaw=parseFloat(document.getElementById('pVal').value)||1;

       var iRaw=parseFloat(document.getElementById('iVal').value)||10;

       var dRaw=parseFloat(document.getElementById('dVal').value)||0;

      

       var kp, ti, td;

      

       if(cfg.algo==='pb'){

               kp=100/pRaw;

               ti=iRaw*60;

               td=dRaw*60;

       }else{

               kp=pRaw;

               var iu=document.getElementById('iUnit').value;

               if(iu==='min'||cfg.iUnit==='min'){

                       ti=iRaw*60;

                       td=dRaw*60;

               }else{

                       ti=iRaw;

                       td=dRaw;

               }

       }

      

       if(ti<0.1)ti=0.1;

      

       var e=sp-pv;

       lerr=e;

       var out=0;

       var dErr=(e-ps.le)/dt;

      

       switch(cfg.algo){

               case 'ideal':

               case 'pb':

                       ps.i+=e*dt;

                       out=kp*(e+ps.i/ti+td*dErr);

                       break;

                       

               case 'noninteractive':

                       ps.i+=e*dt;

                       var pTerm=kp*e;

                       var iTerm=(kp/ti)*ps.i;

                       var dTerm=kp*td*dErr;

                       out=pTerm+iTerm+dTerm;

                       break;

                       

               case 'derivative_first':

                       ps.i+=e*dt;

                       var dPV=-(pv-ps.lpv)/dt;

                       out=kp*(e+ps.i/ti+td*dPV);

                       ps.lpv=pv;

                       break;

                       

               case 'parallel':

                       ps.i+=e*dt;

                       out=kp*e+(kp/ti)*ps.i+kp*td*dErr;

                       break;

                       

               default:

                       out=kp*e;

       }

      

       ps.le=e;

      

       if(out>100){

               out=100;

               if(e>0)ps.i-=e*dt;

       }else if(out<0){

               out=0;

               if(e<0)ps.i-=e*dt;

       }

      

       return out;

}

function calcProc(mv,dt,dist){

       var ty=document.getElementById('objType').value,o=0;

       if(ty=='fopdt'){

               var k=parseFloat(document.getElementById('k').value)||1;

               var ta=parseFloat(document.getElementById('tau').value)||10;

               var th=parseFloat(document.getElementById('theta').value)||0;

               var s=Math.round(th/dt);if(s<0)s=0;

               ps.db.push(mv);

               if(ps.db.length>s){

                       var dm=ps.db.shift();

                       var dy=(k*dm-ps.y)/ta*dt;

                       ps.y+=dy;

               }

               o=ps.y;

       }else if(ty=='int'){

               var k=parseFloat(document.getElementById('ki').value)||0.1;

               ps.y+=k*mv*dt;

               if(ps.y>100)ps.y=100;if(ps.y<0)ps.y=0;

               o=ps.y;

       }else if(ty=='sopdt'){

               var k=parseFloat(document.getElementById('k2').value)||1;

               var t1=parseFloat(document.getElementById('tau1').value)||5;

               var t2=parseFloat(document.getElementById('tau2').value)||5;

               var th=parseFloat(document.getElementById('t2').value)||0;

               var s=Math.round(th/dt);if(s<0)s=0;

               ps.db.push(mv);

               if(ps.db.length>s){

                       var dm=ps.db.shift();

                       var dy1=(dm-ps.y1)/t1*dt;ps.y1+=dy1;

                       var dy=(k*ps.y1-ps.y)/t2*dt;ps.y+=dy;

               }

               o=ps.y;

       }

       o+=dist;

       if(o>100)o=100;if(o<0)o=0;

       return o;

}

function drawChart(){

       var w=cv.width,h=cv.height;

       var p={t:25,r:60,b:35,l:60};

       cx.fillStyle='white';

       cx.fillRect(0,0,w,h);

      

       if(dt.t.length===0){

               drawAxes(w,h,p,0,parseFloat(document.getElementById('tMax').value)||200);

               return;

       }

       var tm=parseFloat(document.getElementById('tMax').value)||200;

       drawAxes(w,h,p,0,tm);

       var gw=w-p.l-p.r,gh=h-p.t-p.b;

       drawLine(dt.t,dt.pv,p,gw,gh,'#ff0000',2.5);

       drawLine(dt.t,dt.sp,p,gw,gh,'#0000ff',2,true);

       drawLine(dt.t,dt.mv,p,gw,gh,'#008000',2);

}

function drawAxes(w,h,p,tmin,tmax){

       cx.strokeStyle='#333';cx.lineWidth=1;

       cx.beginPath();cx.moveTo(p.l,p.t);cx.lineTo(p.l,h-p.b);cx.stroke();

       cx.beginPath();cx.moveTo(p.l,h-p.b);cx.lineTo(w-p.r,h-p.b);cx.stroke();

       cx.beginPath();cx.moveTo(w-p.r,p.t);cx.lineTo(w-p.r,h-p.b);cx.stroke();

      

       cx.fillStyle='#000';cx.font='11px Arial';cx.textAlign='right';

       for(var i=0;i<=100;i+=20){

               var y=(h-p.b)-(i/100)*(h-p.t-p.b);

               cx.fillText(i,p.l-5,y+4);

               cx.beginPath();cx.moveTo(p.l-3,y);cx.lineTo(p.l,y);cx.stroke();

       }

       cx.textAlign='left';

       for(var i=0;i<=100;i+=20){

               var y=(h-p.b)-(i/100)*(h-p.t-p.b);

               cx.fillText(i,w-p.r+5,y+4);

       }

       cx.textAlign='center';

       var st=Math.ceil((tmax-tmin)/10);

       for(var t=0;t<=tmax;t+=st){

               var x=p.l+(t/tmax)*(w-p.l-p.r);

               cx.fillText(t,x,h-p.b+15);

               cx.beginPath();cx.moveTo(x,h-p.b);cx.lineTo(x,h-p.b+5);cx.stroke();

       }

       cx.fillText('时间 (秒)',w/2,h-5);

       cx.save();cx.translate(15,h/2);cx.rotate(-Math.PI/2);cx.textAlign='center';

       cx.fillText('PV / SP (%)',0,0);cx.restore();

       cx.save();cx.translate(w-15,h/2);cx.rotate(Math.PI/2);cx.textAlign='center';

       cx.fillText('MV (%)',0,0);cx.restore();

}

function drawLine(ta,va,p,gw,gh,color,width,dash){

       if(ta.length<2)return;

       var tm=parseFloat(document.getElementById('tMax').value)||200;

       cx.strokeStyle=color;cx.lineWidth=width;

       if(dash)cx.setLineDash([6,4]);else cx.setLineDash([]);

       cx.beginPath();

       for(var i=0;i<ta.length;i++){

               var t=parseFloat(ta),v=parseFloat(va);

               var x=p.l+(t/tm)*gw;

               var y=(p.t+gh)-(v/100)*gh;

               if(i===0)cx.moveTo(x,y);else cx.lineTo(x,y);

       }

       cx.stroke();cx.setLineDash([]);

}

function simStep(){

       try{

               var dt=0.5;

               var spd=parseFloat(document.getElementById('simSpeed').value)||0.5;

               var tm=parseFloat(document.getElementById('tMax').value)||200;

               var sp=parseFloat(document.getElementById('sp').value)||50;

               var st=Math.max(1,Math.round(spd));

               

               for(var i=0;i<st;i++){

                       if(ct>=tm){stop();return;}

                       var d=getDist(ct);

                       var pv=ps.y;

                       var mv=calcPID(sp,pv,dt);

                       lmv=mv;

                       var npv=calcProc(mv,dt,d);

                       if(Math.abs(ct%1)<0.1||ct===0){

                               dt.t.push(ct.toFixed(1));

                               dt.pv.push(npv);

                               dt.sp.push(sp);

                               dt.mv.push(mv);

                               if(dt.t.length>1200){dt.t.shift();dt.pv.shift();dt.sp.shift();dt.mv.shift();}

                       }

                       ct+=dt;

               }

               drawChart();

               document.getElementById('ct').innerHTML=ct.toFixed(1);

               document.getElementById('cpv').innerHTML=ps.y.toFixed(2);

               document.getElementById('cmv').innerHTML=lmv.toFixed(2);

               document.getElementById('cerr').innerHTML=lerr.toFixed(2);

       }catch(e){

               alert('仿真错误:'+e.message);

               stop();

       }

}

function startSim(){

       if(run&&!pausef)return;

       if(!run){dt={t:[],pv:[],sp:[],mv:[]};run=true;}

       pausef=false;

       document.getElementById('st').innerHTML='运行中';

       document.getElementById('btnStart').disabled=true;

       if(tm)clearInterval(tm);

       tm=setInterval(simStep,100);

}

function pauseSim(){

       if(!run)return;

       pausef=!pausef;

       if(pausef){

               clearInterval(tm);tm=null;

               document.getElementById('st').innerHTML='已暂停';

               document.getElementById('btnStart').disabled=false;

       }else startSim();

}

function stop(){

       if(tm)clearInterval(tm);tm=null;

       run=false;pausef=false;

       document.getElementById('st').innerHTML='已完成';

       document.getElementById('btnStart').disabled=false;

}

function resetSim(){

       stop();ct=0;lmv=0;lerr=0;

       ps={y:0,y1:0,i:0,le:0,lpv:0,db:[]};

       dt={t:[],pv:[],sp:[],mv:[]};

       drawChart();

       document.getElementById('st').innerHTML='就绪';

       document.getElementById('ct').innerHTML='0.0';

       document.getElementById('cpv').innerHTML='0.00';

       document.getElementById('cmv').innerHTML='0.00';

       document.getElementById('cerr').innerHTML='0.00';

}

</script>

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码