Please Note: Type CMLFieldType has been changed to CMLFieldEnum. For example, CMLFieldType.ControlBlock has been changed to CMLFieldEnum.ControlBlock in the upcoming 1.5 release.
@AnController( input="this.refPoint - mach.vt + pss.vs - this.washoutBlock.y", output="this.delayBlock.y", refPoint="this.kaDelayBlock.u0 - pss.vs + mach.vt + this.washoutBlock.y", display= {"str.Efd, this.output"} ) public double ka = 50.0, ta = 0.05, vrmax = 10.0, vrmin = 0.0; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.refPoint + pss.vs - mach.vt - this.washoutBlock.y", parameter={"type.NonWindup", "this.ka", "this.ta", "this.vrmax", "this.vrmin"}, y0="this.delayBlock.u0 + this.seFunc.y" ) DelayControlBlock kaDelayBlock;
public double ke1 = 1.0 /* ke1 = 1/Ke */, te_ke = 0.1 /* te_ke = Te/Ke */; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.kaDelayBlock.y - this.seFunc.y", parameter={"type.NoLimit", "this.ke1", "this.te_ke"}, y0="mach.efd" ) DelayControlBlock delayBlock;
public double e1 = 3.1, se_e1 = 0.33, e2 = 2.3, se_e2 = 0.1; @AnFunctionField( input= {"this.delayBlock.y"}, parameter={"this.e1", "this.se_e1", "this.e2", "this.se_e2"} ) SeFunction seFunc;
public double kf = 1.0, tf = 0.05, k = kf/tf; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.delayBlock.y", parameter={"type.NoLimit", "this.k", "this.tf"}, feedback = true ) WashoutControlBlock washoutBlock;Default Parameter
Additional Data Checking Rule: E1 > E2, Se(E1) > Se(E2)
@AnController( input="this.refPoint - mach.vt + pss.vs - this.washoutBlock.y", output="this.delayBlock.y", refPoint="this.delayBlock.u0 - pss.vs + mach.vt + this.washoutBlock.y", display= {"str.Efd, this.output"} ) public double ka = 50.0, ta = 0.05, kp = 10.0, vrmin = 0.0; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.refPoint + pss.vs - mach.vt - this.washoutBlock.y", parameter={"type.Limit", "this.ka", "this.ta", "this.kp * mach.vt", "this.vrmin"}, y0="mach.efd" ) DelayControlBlock delayBlock;
public double kf = 0.1, tf = 0.1, k = kf/tf; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.delayBlock.y", parameter={"type.NoLimit", "this.k", "this.tf"}, feedback = true ) WashoutControlBlock washoutBlock;Default Parameter
@AnController( input="this.refPoint - mach.vt + pss.vs - this.washoutBlock.y", output="this.delayBlock.y", refPoint="this.kaDelayBlock.u0 - pss.vs + mach.vt + this.washoutBlock.y", display= {"str.Efd, this.output"} ) public double ka = 50.0, ta = 0.05, vrmax = 10.0, vrmin = 0.0; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.refPoint + pss.vs - mach.vt - this.washoutBlock.y", parameter={"type.NonWindup", "this.ka", "this.ta", "this.vrmax", "this.vrmin"}, y0="this.delayBlock.u0 + this.seFunc.y" ) DelayControlBlock kaDelayBlock;
public double ke1 = 1.0 /* ke1 = 1.0/Ke */, te_ke = 0.05 /* te_ke = Ke/Ke*/; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.kaDelayBlock.y - this.seFunc.y", parameter={"type.NoLimit", "this.ke1", "this.te_ke"}, y0="mach.efd" ) DelayControlBlock delayBlock;
public double e1 = 3.1, se_e1 = 0.33, e2 = 2.3, se_e2 = 0.1; @AnFunctionField( input= "this.delayBlock.y", parameter={"this.e1", "this.se_e1", "this.e2", "this.se_e2"} ) SeFunction seFunc;
public double kf1 = 1.0, tf1 = 0.05; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.kaDelayBlock.y", parameter={"type.NoLimit", "this.kf1", "this.tf1"}, feedback = true ) DelayControlBlock f2DelayBlock;
public double kf = 1.0, tf = 0.05; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.f2DelayBlock.y", parameter={"type.NoLimit", "this.kf", "this.tf"}, feedback = true ) WashoutControlBlock washoutBlock;Default Parameter
Additional Data Checking Rule: E1 > E2, Se(E1) > Se(E2)
The following custom static block is used to implement the controller model:
The controller model then can be represented in terms of the custom model as follows:
@AnController( input="this.refPoint - mach.vt + pss.vs - this.washoutBlock.y", output="this.delayBlock.y", refPoint="this.kaDelayBlock.u0 - pss.vs + mach.vt + this.washoutBlock.y", display= {"str.Efd, this.output"} )
public double ka = 50.0, ta = 0.05, vrmax = 10.0, vrmin = 0.0; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.refPoint + pss.vs - mach.vt - this.washoutBlock.y", parameter={"type.NonWindup", "this.ka", "this.ta", "this.vrmax", "this.vrmin"}, y0="this.customBlock.u0" ) DelayControlBlock kaDelayBlock; public double kp = 2.0, ki = 1.0, vbmax = 10.0; @AnControllerField( type= CMLFieldEnum.StaticBlock, input= "this.kaDelayBlock.y", y0="this.delayBlock.u0" ) public IStaticBlock customBlock = new StaticBlockAdapter() { private LimitType limit = new LimitType(vbmax, 0.0); private boolean A_gt_1 = false; private double u = 0.0; public boolean initStateY0(double y0) { if ( y0 > vbmax || y0 < 0.0) { getMsgHub().sendWarnMsg("CustomBlock init problem: y0 > vbmax or y0 < 0.0"); return false; } double x = calFunc(); if ( this.A_gt_1 && y0 != 0.0 ) { getMsgHub().sendWarnMsg("CustomBlock init problem: A > 1 and y0 != 0.0"); return false; } this.u = y0 - x; return true; } public double getU0() { return this.u; } public void eulerStep1(double u, double dt) { this.u = u; } public void eulerStep2(double u, double dt) { this.u = u; } public double getY() { double x = calFunc(); if ( this.A_gt_1 ) return 0.0; else { return this.limit.limit(this.u + x); } } private double calFunc() { Machine mach = getMachine(); DStabBus dbus = mach.getDStabBus(); // calculate Ve double vt = mach.getVdq(dbus).abs(); double it = mach.getIdq(dbus).abs(); double ve = new Complex(kp*vt, ki*it).abs(); // calculate sqrt( 1 - A ) double xad = mach.getMachData().getXd() - mach.getMachData().getXl(); double ifd = mach.calculateIfd(dbus); double a = 0.78 * xad * ifd * ifd / ve; if (a > 1.0) { //System.out.println("ve, xad, ifd, a: " + ve + ", " + xad + ", " + ifd + ", " + a); this.A_gt_1 = true; return 0.0; } else { this.A_gt_1 = false; return ve * Math.sqrt(1.0 - a); } } }; public double ke1 = 1.0 /* ke1 = 1/Ke */, te_ke = 0.1 /* te_ke = Te/Ke */; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.customBlock.y", parameter={"type.NoLimit", "this.ke1", "this.te_ke"}, y0="mach.efd" ) DelayControlBlock delayBlock; public double kf = 1.0, tf = 0.05; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.delayBlock.y", parameter={"type.NoLimit", "this.kf", "this.tf"}, feedback = true ) WashoutControlBlock washoutBlock;Default Parameter
@AnController( input="this.refPoint - mach.vt + pss.vs - this.washoutBlock.y", output="this.delayBlock.y", refPoint="this.customBlock.u0 - pss.vs + mach.vt + this.washoutBlock.y", display= {"str.Efd, this.output"} ) public double trh = 1.0, tint = 1.0/trh, kv = 0.05, vrmax = 10.0, vrmin = 0.0; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.refPoint + pss.vs - mach.vt - this.washoutBlock.y", y0="this.delayBlock.u0 + this.seFunc.y" ) public IControlBlock customBlock = new ControlBlockAdapter() { private IntegrationControlBlock block = new IntegrationControlBlock( IStaticBlock.Type.Limit, tint, vrmax, vrmin); public boolean initStateY0(double y0) { return block.initStateY0(y0); } public double getU0(){ return 0.0; } public void eulerStep1(double u, double dt){ block.eulerStep1(u, dt); } public void eulerStep2(double u, double dt){ block.eulerStep2(u, dt); } public double getY(){ double u = block.getU(); if ( u > kv ) return vrmax; else if ( u < -kv ) return vrmin; else return block.getY(); } public double getStateX() { return block.getStateX(); } }; public double ke1 = 1.0 /* ke1 = 1/Ke */, te_ke = 0.1 /* te_ke = Te/Ke */; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.customBlock.y - this.seFunc.y", parameter={"type.NoLimit", "this.ke1", "this.te_ke"}, y0="mach.efd" ) DelayControlBlock delayBlock; public double e1 = 3.1, se_e1 = 0.33, e2 = 2.3, se_e2 = 0.1; @AnFunctionField( input= {"this.delayBlock.y"}, parameter={"this.e1", "this.se_e1", "this.e2", "this.se_e2"} ) SeFunction seFunc; public double kf = 1.0, tf = 0.05; @AnControllerField( type= CMLFieldEnum.ControlBlock, input="this.delayBlock.y", parameter={"type.NoLimit", "this.kf", "this.tf"}, feedback = true ) WashoutControlBlock washoutBlock;Default Parameter