IEEE-1968 Exciter Models

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.

IEEE-1968 Type-1 (Source)

  @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)

IEEE-1968 Type-1s (Source)

  @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

IEEE-1968 Type-2 (Source)

  @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)

IEEE-1968 Type-3 (Source)

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

IEEE-1968 Type-4 (Source)

  @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