void TestFactory2() { //构造进料回路 FeedController fc = ControllerFactory.Create <FeedController>(10); List <PIDConstant> pidcs = new List <PIDConstant>(); PIDConstant pidcIn = new PIDConstant(120, 200, 30, PIDControlAlgorithm.IPD); PIDConstant pidcOut = new PIDConstant(300, 30, 0, PIDControlAlgorithm.PID); pidcs.Add(pidcIn); pidcs.Add(pidcOut); double interval = 1; DynamicObject dynObj = new DynamicObject(20, 5, 3, 0.01, FetchType.Max); for (int i = 0; i < dynObj.Cycle; i++) { dynObj.UpdateDynamic(10 + r.NextDouble() * 2); } fc.GetInstance(pidcs, dynObj, interval, 100); //添加项 for (int i = 0; i < 12; i++) { fc.UpdateDynamic(10 + r.NextDouble() * 2); FeedModel fm = new FeedModel(fc.DynamicList, 50, 52 + r.NextDouble(), 51, 0, 100, 1); fc.AddModel(fm); } }
public FurnaceCollection(PIDConstant pidcIn, PIDConstant pidcOut, FurnaceManage manage, double interval = 1) { this.Interval = interval; this.InPIDConstants = pidcIn; this.OutPIDConstants = pidcOut; this.FurnaceManage = manage; }
public CascadePIDCollection(PIDConstant pidcIn, PIDConstant pidcOut, int k, double interval) { this.K = k; this.Interval = interval; this.InPIDConstants = pidcIn; this.OutPIDConstants = pidcOut; }
void TestFactory() { //构造单回路 SingleController sc = ControllerFactory.Create <SingleController>(5); List <PIDConstant> pidcs = new List <PIDConstant>(); pidcs.Add(new PIDConstant(1, 1, 1, PIDControlAlgorithm.IPD)); sc.GetInstance(pidcs, 1); PIDModel m1 = new PIDModel(50, 49); PIDModel m2 = new PIDModel(50, 49.5); PIDModel m3 = new PIDModel(50, 50.5); PIDModel m4 = new PIDModel(50, 50.8); sc.AddModel(m1); sc.AddModel(m2); sc.AddModel(m3); sc.AddModel(m4); //构造串级 CascadeController cc = ControllerFactory.Create <CascadeController>(5); List <PIDConstant> pidcs2 = new List <PIDConstant>(); PIDConstant pidcIn = new PIDConstant(120, 200, 30, PIDControlAlgorithm.IPD); PIDConstant pidcOut = new PIDConstant(300, 30, 0, PIDControlAlgorithm.PID); pidcs2.Add(pidcIn); pidcs2.Add(pidcOut); cc.GetInstance(pidcs2, 1); CascadePIDModel cm1 = new CascadePIDModel(50, 52, 2000, 1950); cc.AddModel(cm1); //构造复杂串级 MultiCascadeController mcc = ControllerFactory.Create <MultiCascadeController>(5); List <PIDConstant> pidcs3 = new List <PIDConstant>(); PIDConstant pidcIn2 = new PIDConstant(120, 200, 30, PIDControlAlgorithm.IPD); PIDConstant pidcOut2 = new PIDConstant(300, 30, 0, PIDControlAlgorithm.PID); PIDConstant pidcAu1 = new PIDConstant(100, 150, 20, PIDControlAlgorithm.IPD);//附加PID PIDConstant pidcAu2 = new PIDConstant(100, 150, 20, PIDControlAlgorithm.IPD); pidcs3.Add(pidcIn2); pidcs3.Add(pidcOut2); pidcs3.Add(pidcAu1); pidcs3.Add(pidcAu2); mcc.GetInstance(pidcs3, 1); MultiCascadeModel mcm1 = new MultiCascadeModel(50, 52, 2000, 1950, 1); PIDModel aum1 = new PIDModel(20, 19, 1);//附加回路模型 PIDModel aum2 = new PIDModel(20, 19.8, 1); mcm1.AddAuxiliaryModel(aum1); mcm1.AddAuxiliaryModel(aum2); mcc.AddModel(mcm1); }
public MultiCascadePIDCollection(PIDConstant pidcIn, PIDConstant pidcOut, List <PIDConstant> pidcAuxs, double interval = 1) { this.cAcs = new List <PIDCollection>(); this.Interval = interval; this.InPIDConstants = pidcIn; this.OutPIDConstants = pidcOut; this.AuxiliaryConstants = pidcAuxs; }
public PIDCollection(PIDConstant pidc, double interval = 1) { this.Interval = interval; this.PIDConstants = pidc; if (pidc != null) { this.UpdatePIDFunc = pidc.GetPID; } }
public void RemoveAuxiliaryConstant(PIDConstant constant) { if (this.AuxiliaryConstants != null) { this.AuxiliaryConstants.Remove(constant); } if (this.MultiCascadeCollection != null && this.MultiCascadeCollection.AuxiliaryConstants != null) { this.MultiCascadeCollection.AuxiliaryConstants.Remove(constant); } }
public RadioCollection(PIDConstant pidc, int updateFreq, int writeTimes, FetchType fetchType, double diff, double interval = 1) { this.Interval = interval; this.UpdateFrequency = updateFreq; this.WriteTimes = writeTimes; this.FetchType = fetchType; this.Difference = diff; this.PIDConstants = pidc; this.StrategyEnable = false; this.StrategyPeriod = StrategyPeriod.Rest; }
public void RemoveAuxiliaryConstant(PIDConstant constant) { if (this.AuxiliaryConstants != null) { this.AuxiliaryConstants.Remove(constant); } if (this.ComplexRadioCollection != null && this.ComplexRadioCollection.AuxiliaryConstants != null) { this.ComplexRadioCollection.AuxiliaryConstants.Remove(constant); } }
void TestCascade() { PIDConstant pidcIn = new PIDConstant(120, 200, 30, PIDControlAlgorithm.IPD); PIDConstant pidcOut = new PIDConstant(300, 30, 0, PIDControlAlgorithm.PID); CascadePIDCollection cc = new CascadePIDCollection(pidcIn, pidcOut, 1); cc.Maximum = 100; CascadePIDModel m1 = new CascadePIDModel(50, 52, 2000, 1950); cc.Add(m1); }
private void Standardize(int k) { this.K = k; MultiCascadeModel item = this[K]; //输入部分 cIn = this.InitCollection(this.cIn, item, this.InPIDConstants, this.Maximum, ControllerType.MultiCascade, PIDAction.Input); PIDModel inItem = cIn.Last(); item.InP = inItem.P; item.InI = inItem.I; item.InD = inItem.D; item.InDD = inItem.DD; item.InDPV = inItem.DPV; item.InDDPV = inItem.DDPV; item.InVariation = inItem.Variation; //附加部分 if (this.AuxiliaryConstants != null) { for (int i = 0; i < this.AuxiliaryConstants.Count; i++) { PIDConstant ct = this.AuxiliaryConstants[i]; PIDCollection ac = this.cAcs[i]; PIDModel cam = item.AuxiliaryModels[i];//取附加PID模型 ac = this.InitCollection(ac, cam, ct, this.Maximum, ControllerType.Single, PIDAction.None); cam = ac.Last(); item.AuxiliaryModels[i] = cam; this.cAcs[i] = ac; } } //输出部分 cOut = this.InitCollection(this.cOut, item, this.OutPIDConstants, this.Maximum, ControllerType.MultiCascade, PIDAction.Output); PIDModel outItem = cOut.Last(); item.P = outItem.P; item.I = outItem.I; item.D = outItem.D; item.DD = outItem.DD; item.OutDPV = outItem.DPV; item.OutDDPV = outItem.DDPV; item.Variation = outItem.Variation; this.OutCumulativeErr = cOut.CumulativeErr; this.InPIDConstants = cIn.PIDConstants; this.OutPIDConstants = cOut.PIDConstants; this[K] = item; }
public FeedCollection(PIDConstant pidcIn, PIDConstant pidcOut, int updateFreq, int writeTimes, FetchType fetchType, double diff, double interval = 1, double cumulativeErrRange = 0) { this.Interval = interval; this.UpdateFrequency = updateFreq; this.WriteTimes = writeTimes; this.FetchType = fetchType; this.Difference = diff; this.InPIDConstants = pidcIn; this.OutPIDConstants = pidcOut; this.StrategyEnable = false; this.StrategyPeriod = StrategyPeriod.Rest; this.CumulativeErrRange = cumulativeErrRange; }
void TestFactory3() { //构造间隔回路 SwitchController sc = ControllerFactory.Create <SwitchController>(); sc.GetInstance(3); SwitchModel sm1 = new SwitchModel(50, 40, 10, 2); SwitchModel sm2 = new SwitchModel(50, 45, 10, 2); SwitchModel sm3 = new SwitchModel(50, 52, 10, 2); SwitchModel sm4 = new SwitchModel(50, 61, 10, 2); SwitchModel sm5 = new SwitchModel(50, 56, 10, 2); sc.AddModel(sm1); sc.AddModel(sm2); sc.AddModel(sm3); sc.AddModel(sm4); sc.AddModel(sm5); //构造加热炉回路 FurnaceController fc = ControllerFactory.Create <FurnaceController>(100); List <PIDConstant> pidcs2 = new List <PIDConstant>(); PIDConstant pidcIn = new PIDConstant(120, 200, 30, PIDControlAlgorithm.IPD); PIDConstant pidcOut = new PIDConstant(300, 30, 0, PIDControlAlgorithm.PID); pidcs2.Add(pidcIn); pidcs2.Add(pidcOut); FurnaceManage manage = new FurnaceManage(20, 5); fc.GetInstance(pidcs2, manage, 1); FurnaceModel fm1 = new FurnaceModel(50, 51, 52, 53, 1); FurnaceModel fm2 = new FurnaceModel(50, 52, 52, 55, 1); FurnaceModel fm3 = new FurnaceModel(50, 50.5, 52, 54, 1); FurnaceModel fm4 = new FurnaceModel(50, 50, 52, 52, 1); FurnaceModel fm5 = new FurnaceModel(50, 51.2, 52, 53, 1); FurnaceModel fm6 = new FurnaceModel(50, 53, 52, 56, 1); FurnaceModel fm7 = new FurnaceModel(50, 52.2, 52, 54, 1); FurnaceModel fm8 = new FurnaceModel(50, 51.6, 52, 55, 1); fc.AddModel(fm1); fc.AddModel(fm2); fc.AddModel(fm3); fc.AddModel(fm4); fc.AddModel(fm5); fc.AddModel(fm6); fc.AddModel(fm7); fc.AddModel(fm8); }
public PIDConstant GetPID(PIDConstant cst, PIDModel item) { if (cst != null && cst.ComputeParams != null) { var cps = cst.ComputeParams; double tmpP = cps.P0 - cps.a * item.D * cps.b * item.DD; double tmpI = cps.I0 - cps.m * item.Err * cps.n * item.DD; double tmpD = cps.D0 + cps.k * Math.Abs(item.DD); this.CP = Math.Min(cps.PMax, Math.Max(cps.PMin, tmpP)); this.TI = Math.Min(cps.IMax, Math.Max(cps.IMin, tmpI)); this.TD = Math.Min(cps.DMax, Math.Max(cps.DMin, tmpD)); } return(this); }
void TestSingle() { PIDConstant pidc = new PIDConstant(1, 1, 1); PIDCollection c = new PIDCollection(pidc); c.Maximum = 5; c.E = i => c[i].Err; PIDModel m1 = new PIDModel(50, 70); PIDModel m2 = new PIDModel(50, 60); PIDModel m3 = new PIDModel(50, 53); PIDModel m4 = new PIDModel(50, 49); PIDModel m5 = new PIDModel(50, 51); PIDModel m6 = new PIDModel(50, 48); PIDModel m7 = new PIDModel(50, 52); PIDModel m8 = new PIDModel(50, 51); PIDModel m9 = new PIDModel(50, 46); PIDModel m10 = new PIDModel(50, 52); PIDModel m11 = new PIDModel(50, 50.2); PIDModel m12 = new PIDModel(50, 49); PIDModel m13 = new PIDModel(50, 50.5); PIDModel m14 = new PIDModel(50, 49.2); c.Add(m1); c.Add(m2); c.Add(m3); c.Add(m4); c.Add(m5); c.Add(m6); c.Add(m7); c.Add(m8); c.Add(m9); c.Add(m10); c.Add(m11); c.Add(m12); c.Add(m13); c.Add(m14); //var v = from t in c // select t.Variation; //double s = v.Sum(); //c.Standardize(); }
public ComplexRadioCollection(PIDConstant pidcIn, PIDConstant pidcOut, List <PIDConstant> pidcAuxs, int updateFreq, int writeTimes, FetchType fetchType, double diff, List <double> cumulativeErrRanges, double interval = 1) { this.cAcs = new List <PIDCollection>(); this.Interval = interval; this.UpdateFrequency = updateFreq; this.WriteTimes = writeTimes; this.FetchType = fetchType; this.Difference = diff; this.InPIDConstants = pidcIn; this.OutPIDConstants = pidcOut; this.StrategyEnable = false; this.StrategyPeriod = StrategyPeriod.Rest; this.InPIDConstants = pidcIn; this.OutPIDConstants = pidcOut; this.AuxiliaryConstants = pidcAuxs; this.CumulativeErrRanges = cumulativeErrRanges; }
public override void GetInstance(PIDConstant constant, SimpleDynamicObject dynObj, double baseInterval) { //if (dynObj != null) //{ // //参数匹配检测 // if (dynObj.Interval != baseInterval) // { // string msg = InnerArgumentException.GenInfo(nameof(dynObj.Interval), dynObj, nameof(baseInterval), baseInterval); // throw new InnerArgumentException(msg); // } //} this.DynamicObject = dynObj; if (constant != null && dynObj != null) { this.BaseInterval = baseInterval; this.RadioConstant = constant; this.RadioCollection = new RadioCollection(this.RadioConstant, dynObj.UpdateFrequency, dynObj.WriteTimes, dynObj.FetchType, dynObj.Difference, this.BaseInterval); this.RadioCollection.Maximum = this.Maximun; this.StrategySwitch = true; } }
public SplitRangingCollection(PIDConstant pidcIn, PIDConstant pidcOut, double interval = 1) { this.Interval = interval; }
/// <summary> /// 用于比例控制器 /// </summary> /// <param name="constant">PID回路参数</param> /// <param name="dynObj">基础动态修正对象</param> /// <param name="baseInterval">执行间隔</param> public virtual void GetInstance(PIDConstant constant, SimpleDynamicObject dynObj, double baseInterval) { }
private void Standardize(int k) { this.K = k; ComplexRadioModel item = this[K]; //输入部分 cIn = this.InitCollection(cIn, item, this.InPIDConstants, this.Maximum, ControllerType.ComplexRadio, PIDAction.Input, this.CumulativeErrRanges[0]); PIDModel inItem = cIn.Last(); item.InP = inItem.P; item.InI = inItem.I; item.InD = inItem.D; item.InDD = inItem.DD; item.InDPV = inItem.DPV; item.InDDPV = inItem.DDPV; item.InVariation = inItem.Variation; this.InCumulativeErr = cIn.CumulativeErr; //附加部分 if (this.AuxiliaryConstants != null) { for (int i = 0; i < this.AuxiliaryConstants.Count; i++) { PIDConstant ct = this.AuxiliaryConstants[i]; PIDCollection ac = this.cAcs[i]; PIDModel cam = item.AuxiliaryModels[i];//取附加PID模型 ac = this.InitCollection(ac, cam, ct, this.Maximum, ControllerType.Single, PIDAction.None, this.CumulativeErrRanges[i + 1]); cam = ac.Last(); item.AuxiliaryModels[i] = cam; this.cAcs[i] = ac; } } double axVals = 0;//附加输入回路计算变化量 if (item.AuxiliaryModels != null && item.AuxiliaryModels.Count > 0) { axVals = item.AuxiliaryModels.Sum(m => m.Variation); } //开关启动 if (this.StrategySwitch) { bool pcheck = IsCheck(this.serialIndex, this.UpdateFrequency); //该轮是否进行检测 bool doStrategy = false; //UpdateFrequency为1时,不启用策略 if (this.UpdateFrequency == 1) { doStrategy = false; } else if (this.StrategyPeriod == StrategyPeriod.Rest) { //当前为休息周期,且进行检测 if (pcheck) { this.InitStrategy(); //满足条件,启用策略 if (this.StrategyEnable) { this.StrategyPeriod = StrategyPeriod.Running;//转换状态为运行 doStrategy = true; } //不满足条件,不启用策略,且保持休息周期状态 else { doStrategy = false; } } //当前为休息周期,且不进行检测 else { doStrategy = false; } } else if (this.StrategyPeriod == StrategyPeriod.Running) { //当前为运行周期,且进行检测 if (pcheck) { //紧邻运行周期的下一周期进行休息 this.StrategyPeriod = StrategyPeriod.Rest; this.StrategyObject = null; doStrategy = false; } //当前为运行周期,且不进行检测 else { doStrategy = true; } } //执行检测 if (pcheck) { //执行策略 if (doStrategy) { if (this.StrategyObject != null) { if (this.StrategyObject.Index < this.StrategyObject.ComputeCount) { item.OutSV = cIn.CumulativeVariation + axVals + (this.StrategyObject.BasicValue + this.StrategyObject.Diff * (this.StrategyObject.Index + 1) / this.StrategyObject.ComputeCount) * item.UniFactor; } this.StrategyObject.GoNext(); } } else { item.OutSV = cIn.CumulativeVariation + axVals + item.RPV * item.ScaleFactor * item.UniFactor; } } //不执行检测 else { if (this.K > 0) { item.OutSV = this[K - 1].OutSV; } else { item.OutSV = 0; } } } //开关未启动 else { item.OutSV = cIn.CumulativeVariation + axVals + item.RPV * item.ScaleFactor * item.UniFactor; } //输出部分 cOut = this.InitCollection(cOut, item, this.OutPIDConstants, this.Maximum, ControllerType.ComplexRadio, PIDAction.Output); PIDModel outItem = cOut.Last(); item.P = outItem.P; item.I = outItem.I; item.D = outItem.D; item.DD = outItem.DD; item.OutDPV = outItem.DPV; item.OutDDPV = outItem.DDPV; item.Variation = outItem.Variation; this.OutCumulativeErr = cOut.CumulativeErr; this.InPIDConstants = cIn.PIDConstants; this.OutPIDConstants = cOut.PIDConstants; this[K] = item; }
public PIDCollection InitCollection(PIDCollection c, PIDModel item, PIDConstant pidc, int maximum, ControllerType ct = ControllerType.Single, PIDAction action = PIDAction.None, double cumulativeErrRange = 0) { if (c == null) { c = new PIDCollection(pidc, item.Interval); } else { c.PIDConstants = pidc; c.Interval = item.Interval; } c.CumulativeErrRange = cumulativeErrRange; c.Maximum = maximum; c.E = i => c[i].Err; switch (ct) { case ControllerType.Single: PIDModel m = new PIDModel(item.SV, item.PV, item.Interval); c.Add(m); break; case ControllerType.Cascade: CascadePIDModel cm = item as CascadePIDModel; PIDModel m2 = null; if (action == PIDAction.Input) { m2 = new PIDModel(cm.InSV, cm.InPV, cm.Interval); } else if (action == PIDAction.Output) { m2 = new PIDModel(cm.OutSV, cm.OutPV, cm.Minimum, cm.Maximum, cm.Interval); } c.Add(m2); break; case ControllerType.MultiCascade: MultiCascadeModel mcm = item as MultiCascadeModel; PIDModel m3 = null; if (action == PIDAction.Input) { m3 = new PIDModel(mcm.InSV, mcm.InPV, mcm.Interval); } else if (action == PIDAction.Output) { m3 = new PIDModel(mcm.OutSV, mcm.OutPV, mcm.Minimum, mcm.Maximum, mcm.Interval); } c.Add(m3); break; case ControllerType.Feed: FeedModel fm = item as FeedModel; PIDModel m4 = null; if (action == PIDAction.Input) { m4 = new PIDModel(fm.InSV, fm.InPV, fm.Interval); } else if (action == PIDAction.Output) { m4 = new PIDModel(fm.OutSV + fm.CorrectionValue, fm.OutPV, fm.Minimum, fm.Maximum, fm.Interval); } c.Add(m4); break; case ControllerType.Radio: RadioModel rm = item as RadioModel; PIDModel m5 = new PIDModel(rm.SV + rm.CorrectionValue, rm.PV, rm.Interval); c.Add(m5); break; case ControllerType.ComplexRadio: ComplexRadioModel crm = item as ComplexRadioModel; PIDModel m6 = null; if (action == PIDAction.Input) { m6 = new PIDModel(crm.InSV, crm.InPV, crm.Interval); } else if (action == PIDAction.Output) { m6 = new PIDModel(crm.OutSV + crm.CorrectionValue, crm.OutPV, crm.Minimum, crm.Maximum, crm.Interval); } c.Add(m6); break; case ControllerType.Furnace: FurnaceModel fum = item as FurnaceModel; PIDModel m7 = null; if (action == PIDAction.Input) { m7 = new PIDModel(fum.InSV, fum.InPV, fum.Interval); } else if (action == PIDAction.Output) { m7 = new PIDModel(fum.OutSV, fum.OutPV, fum.Minimum, fum.Maximum, fum.Interval); } c.Add(m7); break; } return(c); }