Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
 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;
 }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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;
        }
Esempio n. 6
0
 public PIDCollection(PIDConstant pidc, double interval = 1)
 {
     this.Interval     = interval;
     this.PIDConstants = pidc;
     if (pidc != null)
     {
         this.UpdatePIDFunc = pidc.GetPID;
     }
 }
Esempio n. 7
0
 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);
     }
 }
Esempio n. 8
0
 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;
 }
Esempio n. 9
0
 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);
     }
 }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        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;
        }
Esempio n. 12
0
        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;
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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);
        }
Esempio n. 15
0
        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;
        }
Esempio n. 17
0
        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;
            }
        }
Esempio n. 18
0
 public SplitRangingCollection(PIDConstant pidcIn, PIDConstant pidcOut, double interval = 1)
 {
     this.Interval = interval;
 }
Esempio n. 19
0
 /// <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;
        }
Esempio n. 21
0
        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);
        }