model VoltageController "Voltage controller"
import Modelica.Constants.pi;
constant Integer m = 3 "Number of phases";
parameter Integer p "Number of pole pairs";
parameter Modelica.SIunits.Frequency fsNominal "Nominal frequency";
parameter Modelica.SIunits.Voltage VsOpenCircuit "Open circuit RMS voltage per phase @ fsNominal";
parameter Modelica.SIunits.Resistance Rs "Stator resistance per phase";
parameter Modelica.SIunits.Inductance Ld "Inductance in d-axis";
parameter Modelica.SIunits.Inductance Lq "Inductance in q-axis";
parameter Boolean decoupling = false "Use decoupling network";
final parameter Modelica.SIunits.MagneticFlux psiM = sqrt(2) * VsOpenCircuit / (2 * pi * fsNominal);
Modelica.SIunits.AngularVelocity omega = p * der(phi);
Modelica.SIunits.Voltage Vd = sqrt(2) * (Rs * id_rms - omega * Lq * iq_rms);
Modelica.SIunits.Voltage Vq = sqrt(2) * (Rs * iq_rms + omega * Ld * id_rms) + omega * psiM;
extends Modelica.Blocks.Interfaces.MO(final nout = m);
Modelica.Blocks.Interfaces.RealInput id_rms annotation (Placement(transformation(extent = {
{-140, 40},
{-100, 80}})));
Modelica.Blocks.Interfaces.RealInput iq_rms annotation (Placement(transformation(extent = {
{-140, -80},
{-100, -40}})));
Modelica.Blocks.Interfaces.RealInput phi(unit = "rad") annotation (Placement(transformation(
origin = {60, -120},
extent = {
{20, -20},
{-20, 20}},
rotation = 270)));
Modelica.Blocks.Interfaces.RealInput iActual[m] annotation (Placement(transformation(
origin = {-60, -120},
extent = {
{20, -20},
{-20, 20}},
rotation = 270)));
Machines.Utilities.FromDQ fromDQ(final p = p, final m = m) annotation (Placement(transformation(extent = {
{70, -10},
{90, 10}})));
Machines.Utilities.ToDQ toDQ(final p = p, final m = m) annotation (Placement(transformation(
extent = {
{-10, -10},
{10, 10}},
rotation = 90,
origin = {-60, -80})));
Modelica.Blocks.Math.Gain toPeak_d(final k = sqrt(2)) annotation (Placement(transformation(
extent = {
{-10, -10},
{10, 10}},
origin = {-70, 60})));
Modelica.Blocks.Math.Gain toPeak_q(final k = sqrt(2)) annotation (Placement(transformation(
extent = {
{-10, -10},
{10, 10}},
origin = {-70, 0})));
Modelica.Blocks.Math.Feedback feedback_d annotation (Placement(transformation(extent = {
{-38, 50},
{-18, 70}})));
Modelica.Blocks.Math.Feedback feedback_q annotation (Placement(transformation(extent = {
{-40, -10},
{-20, 10}})));
Modelica.Blocks.Continuous.PI PI_d(final k = unitResistance / Rs, final T = Ld / Rs, initType = Modelica.Blocks.Types.Init.InitialOutput) annotation (Placement(transformation(extent = {
{-10, 50},
{10, 70}})));
Modelica.Blocks.Continuous.PI PI_q(final k = unitResistance / Rs, final T = Lq / Rs, initType = Modelica.Blocks.Types.Init.InitialOutput) annotation (Placement(transformation(extent = {
{-10, -10},
{10, 10}})));
Modelica.Blocks.Math.Add add[2](final k1 = fill(1, 2), final k2 = fill(if decoupling then 1 else 0, 2)) annotation (Placement(transformation(extent = {
{32, -10},
{52, 10}})));
Modelica.Blocks.Sources.RealExpression deCoupling[2](y = {Vd, Vq}) annotation (Placement(transformation(extent = {
{-10, -40},
{10, -20}})));
protected
constant Modelica.SIunits.Resistance unitResistance = 1 annotation (HideResult = true);
equation
connect(iActual,toDQ.u) annotation (Line(
points = {
{-60, -120},
{-60, -92}},
color = {0, 0, 127}));
connect(phi,fromDQ.phi) annotation (Line(
points = {
{60, -120},
{60, -80},
{80, -80},
{80, -12}},
color = {0, 0, 127}));
connect(phi,toDQ.phi) annotation (Line(
points = {
{60, -120},
{60, -80},
{-48, -80}},
color = {0, 0, 127}));
connect(PI_d.y,add[1].u1) annotation (Line(
points = {
{11, 60},
{20, 60},
{20, 6},
{30, 6}},
color = {0, 0, 127}));
connect(PI_q.y,add[2].u1) annotation (Line(
points = {
{11, 0},
{20, 0},
{20, 6},
{30, 6}},
color = {0, 0, 127}));
connect(add.y,fromDQ.u) annotation (Line(
points = {
{53, 0},
{68, 0}},
color = {0, 0, 127}));
connect(fromDQ.y,y) annotation (Line(
points = {
{91, 0},
{110, 0}},
color = {0, 0, 127}));
connect(toDQ.y[1],feedback_d.u2) annotation (Line(
points = {
{-60, -69},
{-60, -60},
{-50, -60},
{-50, 40},
{-28, 40},
{-28, 52}},
color = {0, 0, 127}));
connect(toDQ.y[2],feedback_q.u2) annotation (Line(
points = {
{-60, -69},
{-60, -60},
{-50, -60},
{-50, -20},
{-30, -20},
{-30, -8}},
color = {0, 0, 127}));
connect(toPeak_d.u,id_rms) annotation (Line(
points = {
{-82, 60},
{-120, 60}},
color = {0, 0, 127}));
connect(toPeak_d.y,feedback_d.u1) annotation (Line(
points = {
{-59, 60},
{-36, 60}},
color = {0, 0, 127}));
connect(toPeak_q.u,iq_rms) annotation (Line(
points = {
{-82, 0},
{-90, 0},
{-90, -60},
{-120, -60}},
color = {0, 0, 127}));
connect(toPeak_q.y,feedback_q.u1) annotation (Line(
points = {
{-59, 0},
{-38, 0}},
color = {0, 0, 127}));
connect(deCoupling.y,add.u2) annotation (Line(
points = {
{11, -30},
{20, -30},
{20, -6},
{30, -6}},
color = {0, 0, 127}));
connect(feedback_d.y,PI_d.u) annotation (Line(
points = {
{-19, 60},
{-12, 60}},
color = {0, 0, 127}));
connect(feedback_q.y,PI_q.u) annotation (Line(
points = {
{-21, 0},
{-12, 0}},
color = {0, 0, 127}));
annotation (
Icon(graphics = {
Text(
extent = {
{-100, 60},
{20, 40}},
lineColor = {0, 0, 255},
textString = "id_rms"),
Text(
extent = {
{-100, -40},
{20, -60}},
lineColor = {0, 0, 255},
textString = "iq_rms")}),
Documentation(info = "<html>\n<p>\nSimple Voltage-Controller\n</p>\n<p>\nThe desired rms values of d- and q-component of the space phasor current in rotor fixed coordinate system are given by inputs \"id_rms\" and \"iq_rms\".\nUsing the given rotor position (input \"phi\"), the actual threephase currents are measured and transformed to the d-q coordinate system.\nTwo PI-controller determine the necessary d- and q- voltages, which are transformed back to threephase (output \"y[3]\").\nThey can be used to feed a voltage source which in turn feeds a permanent magnet synchronous machine.\n</p>\n<p>\nNote: No care is taken for current or voltage limiting, as well as for field weakening.\n</p>\n</html>"));
end VoltageController;