'PI-Controller doesn't reach reference value with inverter and PMSM in Modelica

I'm trying to investigate the Modelica example Modelica.Electrical.Machines.Examples.SynchronousInductionMachines.SMPM_VoltageSource but I replaced the signalVoltage by an inverter and a PWM block signalPWM which is based on Modelica.Electrical.PowerConverters.DCDC.Control.SignalPWM. So instead of sine voltages I want to investigate PWM modulated voltages. The problem is that the controller keeps increasing its output linearily because of the integrating part of the controller as it never reaches the reference value of the desired q-current. In addition it outputs strange values for voltageController.y[1] in the range of [24E3,...,150E3], which is probrably the problem.

The controller output: enter image description here

and the current output: enter image description here

Unfortunately I don't understand why the controller works fine with the sine voltages and doesnt with the PWM voltages.

Below is my main model:

model SMPM_INV_SineLoad "Test example: PermanentMagnetSynchronousInductionMachine fed by FOC"
  extends Modelica.Icons.Example;
  import Modelica.Constants.pi;
  constant Integer m = 3 "Number of phases";
  parameter Modelica.SIunits.Frequency f = 8000 "Switching frequency";
  parameter Modelica.SIunits.AngularVelocity wRef = 30 "Desired speed of the PMSM";
  parameter Modelica.SIunits.Current Idq[2] = {0, 10} "Desired d- and q-current";
  parameter Modelica.SIunits.AngularVelocity wNominal = 2 * pi * smpmData.fsNominal / smpmData.p "Nominal speed";
  parameter Modelica.SIunits.Torque TLoad = 5 "Nominal load torque";
  parameter Modelica.SIunits.Inertia JLoad = 0.29 "Load's moment of inertia";
  parameter Modelica.SIunits.Voltage VBat_2 = 100 "Half Battery Voltage";
  Modelica.Electrical.Machines.BasicMachines.SynchronousInductionMachines.SM_PermanentMagnet smpm(phiMechanical(start = 0, fixed = true), wMechanical(start = 0, fixed = true), useSupport = false, useThermalPort = false, p = smpmData.p, fsNominal = smpmData.fsNominal, Rs = smpmData.Rs, TsRef = smpmData.TsRef, Lszero = smpmData.Lszero, Lssigma = smpmData.Lssigma, Jr = smpmData.Jr, Js = smpmData.Js, frictionParameters = smpmData.frictionParameters, statorCoreParameters = smpmData.statorCoreParameters, strayLoadParameters = smpmData.strayLoadParameters, VsOpenCircuit = smpmData.VsOpenCircuit, Lmd = smpmData.Lmd, Lmq = smpmData.Lmq, useDamperCage = smpmData.useDamperCage, Lrsigmad = smpmData.Lrsigmad, Lrsigmaq = smpmData.Lrsigmaq, Rrd = smpmData.Rrd, Rrq = smpmData.Rrq, TrRef = smpmData.TrRef, permanentMagnetLossParameters = smpmData.permanentMagnetLossParameters, TsOperational = 293.15, alpha20s = smpmData.alpha20s, TrOperational = 293.15, alpha20r = smpmData.alpha20r) annotation(Placement(transformation(extent = {{-20, -50}, {0, -30}}, origin = {-0, -10}, rotation = 0), visible = true));
  Modelica.Electrical.Machines.Utilities.TerminalBox terminalBox(terminalConnection = "Y") annotation(Placement(transformation(extent = {{-20, -34}, {0, -14}}, origin = {-0, -10}, rotation = 0), visible = true));
  Modelica.Mechanics.Rotational.Sensors.AngleSensor angleSensor annotation(Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 90, origin = {20, -10}), visible = true));
  Modelica.Mechanics.Rotational.Components.Inertia inertiaLoad(J = JLoad) annotation(Placement(transformation(extent = {{50, -50}, {70, -30}}, origin = {-0, -10}, rotation = 0), visible = true));
  Modelica.Electrical.MultiPhase.Sensors.CurrentSensor currentSensor(m = m) annotation(Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 270, origin = {-10, -10}), visible = true));
  Modelica.Electrical.Machines.Utilities.VoltageController voltageController(p = smpm.p, Ld = smpm.Lssigma + smpm.Lmd, Lq = smpm.Lssigma + smpm.Lmq, Rs = Modelica.Electrical.Machines.Thermal.convertResistance(smpm.Rs, smpm.TsRef, smpm.alpha20s, smpm.TsOperational), fsNominal = smpm.fsNominal, VsOpenCircuit = smpm.VsOpenCircuit) annotation(Placement(transformation(extent = {{-50, 40}, {-30, 60}}, origin = {-0, -10}, rotation = 0), visible = true));
  Modelica.Mechanics.Rotational.Sensors.TorqueSensor torqueSensor annotation(Placement(transformation(extent = {{10, 10}, {-10, -10}}, rotation = 180, origin = {40, -70}), visible = true));
  Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor annotation(Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 90, origin = {50, -10}), visible = true));
  Modelica.Electrical.Machines.Sensors.RotorDisplacementAngle rotorDisplacementAngle(p = smpm.p) annotation(Placement(transformation(origin = {20, -50}, extent = {{-10, 10}, {10, -10}}, rotation = 270), visible = true));
  Modelica.Electrical.Analog.Basic.Ground groundM annotation(Placement(transformation(origin = {-80, -38}, extent = {{-10, -10}, {10, 10}}, rotation = 270), visible = true));
  Modelica.Electrical.MultiPhase.Basic.Star starM(final m = m) annotation(Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 180, origin = {-60, -20}), visible = true));
  Modelica.Electrical.Machines.Sensors.VoltageQuasiRMSSensor voltageQuasiRMSSensor annotation(Placement(transformation(extent = {{-10, 10}, {10, -10}}, rotation = 180, origin = {-30, -20}), visible = true));
  parameter Modelica.Electrical.Machines.Utilities.ParameterRecords.SM_PermanentMagnetData smpmData(useDamperCage = false) annotation(Placement(transformation(extent = {{-20, -80}, {0, -60}}, origin = {-0, -10}, rotation = 0), visible = true));
  Modelica.Electrical.Machines.Sensors.CurrentQuasiRMSSensor currentQuasiRMSSensor annotation(Placement(transformation(origin = {-10, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 270), visible = true));
  Modelica.Mechanics.Rotational.Sources.SignTorque signTorque1(tau_constant = -TLoad, w0 = wNominal) annotation(Placement(visible = true, transformation(origin = {90, -50}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  Modelica.Blocks.Sources.Constant id(k = Idq[1]) annotation(Placement(transformation(extent = {{-90, 60}, {-70, 80}}, origin = {-0, -10}, rotation = 0), visible = true));
  SignalPWM signalPWM1[m](useConstantDutyCycle = false, f = f) annotation(Placement(visible = true, transformation(origin = {22.087, 64.88}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Electrical.PowerConverters.DCAC.MultiPhase2Level multiPhase2Level1 annotation(Placement(visible = true, transformation(origin = {22.083, 116.565}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Electrical.Analog.Sources.ConstantVoltage U_n(V = VBat_2) annotation(Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 270, origin = {-30, 97.365}), visible = true));
  Modelica.Electrical.Analog.Basic.Ground ground annotation(Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 180, origin = {-50, 127.365}), visible = true));
  Modelica.Electrical.Analog.Sources.ConstantVoltage U_p(V = VBat_2) annotation(Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 270, origin = {-30, 137.365}), visible = true));
  Modelica.Blocks.Sources.Constant iq(k = Idq[2]) annotation(Placement(transformation(extent = {{-90, 20}, {-70, 40}}, origin = {0, -10}, rotation = 0), visible = true));
initial equation
  smpm.is[1:2] = zeros(2);
equation
  connect(terminalBox.plug_sn, smpm.plug_sn) annotation(Line(points = {{0, 0}, {0, 0}, {0, 0}}, color = {0, 0, 255}, visible = true, origin = {-16, -40}));
  connect(terminalBox.plug_sp, smpm.plug_sp) annotation(Line(points = {{0, 0}, {0, 0}, {0, 0}}, color = {0, 0, 255}, visible = true, origin = {-4, -40}));
  connect(smpm.flange, angleSensor.flange) annotation(Line(points = {{-6.667, -10}, {3.333, -10}, {3.333, 20}, {13.333, 20}}, visible = true, origin = {6.667, -40}, color = {64, 64, 64}));
  connect(currentSensor.plug_n, terminalBox.plugSupply) annotation(Line(points = {{-10, -10}, {-10, -28}}, color = {10, 90, 224}, visible = true, origin = {-0, -10}));
  connect(angleSensor.phi, voltageController.phi) annotation(Line(points = {{20, 11}, {20, 34}, {-34, 34}, {-34, 38}}, color = {1, 37, 163}, visible = true, origin = {0, -10}));
  connect(currentSensor.i, voltageController.iActual) annotation(Line(points = {{-21, 0}, {-46, 0}, {-46, 38}}, color = {1, 37, 163}, visible = true, origin = {-0, -10}));
  connect(inertiaLoad.flange_a, torqueSensor.flange_b) annotation(Line(points = {{50, -40}, {50, -60}}, visible = true, origin = {-0, -10}, color = {64, 64, 64}));
  connect(torqueSensor.flange_a, smpm.flange) annotation(Line(points = {{30, -60}, {30, -40}, {0, -40}}, visible = true, origin = {-0, -10}, color = {64, 64, 64}));
  connect(speedSensor.flange, smpm.flange) annotation(Line(points = {{23.333, 20}, {13.333, 20}, {13.333, -10}, {-26.667, -10}}, visible = true, origin = {26.667, -40}, color = {64, 64, 64}));
  connect(rotorDisplacementAngle.flange, smpm.flange) annotation(Line(points = {{10, -40}, {0, -40}}, visible = true, origin = {-0, -10}, color = {64, 64, 64}));
  connect(rotorDisplacementAngle.plug_p, smpm.plug_sp) annotation(Line(points = {{14, -30}, {-4, -30}}, color = {10, 90, 224}, visible = true, origin = {-0, -10}));
  connect(rotorDisplacementAngle.plug_n, smpm.plug_sn) annotation(Line(points = {{26, -30}, {26, -20}, {-16, -20}, {-16, -30}}, color = {10, 90, 224}, visible = true, origin = {-0, -10}));
  connect(voltageQuasiRMSSensor.plug_p, currentSensor.plug_n) annotation(Line(points = {{-20, -10}, {-10, -10}}, color = {10, 90, 224}, visible = true, origin = {-0, -10}));
  connect(starM.plug_p, voltageQuasiRMSSensor.plug_n) annotation(Line(points = {{-50, -10}, {-40, -10}}, color = {10, 90, 224}, visible = true, origin = {-0, -10}));
  connect(groundM.p, starM.pin_n) annotation(Line(points = {{-70, -28}, {-70, -10}}, color = {10, 90, 224}, visible = true, origin = {-0, -10}));
  connect(currentQuasiRMSSensor.plug_n, currentSensor.plug_p) annotation(Line(points = {{0, 0}, {0, 0}, {0, 0}}, color = {0, 0, 255}, visible = true, origin = {-10, 0}));
  connect(inertiaLoad.flange_b, signTorque1.flange) annotation(Line(visible = true, origin = {75, -50}, points = {{-5, 0}, {5, 0}}, color = {64, 64, 64}));
  connect(id.y, voltageController.id_rms) annotation(Line(points = {{-69, 70}, {-60, 70}, {-60, 56}, {-52, 56}}, color = {1, 37, 163}, visible = true, origin = {-0, -10}));
  connect(voltageController.y[1:3], signalPWM1[1:3].dutyCycle) annotation(Line(visible = true, origin = {-16.728, 52.44}, points = {{-12.272, -12.44}, {-7.272, -12.44}, {-7.272, 12.44}, {26.815, 12.44}}, color = {1, 37, 163}));
  connect(ground.p, U_n.p) annotation(Line(visible = true, origin = {-40, 112.78}, points = {{-10, 4.585}, {-10, 4.557}, {10, 4.557}, {10, -5.415}}, color = {10, 90, 224}));
  connect(U_p.n, U_n.p) annotation(Line(visible = true, origin = {-30, 117.365}, points = {{0, 10}, {0, -10}}, color = {10, 90, 224}));
  connect(U_n.n, multiPhase2Level1.dc_n) annotation(Line(visible = true, origin = {-15.583, 93.045}, points = {{-14.417, -5.68}, {-14.417, -10.68}, {0.583, -10.68}, {0.583, 13.52}, {27.666, 13.52}}, color = {10, 90, 224}));
  connect(U_p.p, multiPhase2Level1.dc_p) annotation(Line(visible = true, origin = {-15.583, 141.045}, points = {{-14.417, 6.32}, {-14.417, 11.32}, {0.583, 11.32}, {0.583, -14.48}, {27.666, -14.48}}, color = {10, 90, 224}));
  connect(signalPWM1[1:3].fire, multiPhase2Level1.fire_p[1:3]) annotation(Line(visible = true, origin = {16.085, 85.551}, points = {{0.002, -9.671}, {0.002, -4.671}, {-0.002, -4.671}, {-0.002, 19.014}}, color = {190, 52, 178}));
  connect(signalPWM1[1:3].notFire, multiPhase2Level1.fire_n[1:3]) annotation(Line(visible = true, origin = {28.085, 85.551}, points = {{0.002, -9.671}, {0.002, -4.671}, {-0.002, -4.671}, {-0.002, 19.014}}, color = {190, 52, 178}));
  connect(multiPhase2Level1.ac, currentQuasiRMSSensor.plug_p) annotation(Line(visible = true, origin = {22.417, 66.626}, points = {{9.666, 49.939}, {27.583, 49.939}, {27.583, -26.626}, {-32.417, -26.626}, {-32.417, -46.626}}, color = {10, 90, 224}));
  connect(iq.y, voltageController.iq_rms) annotation(Line(visible = true, origin = {-62.25, 27}, points = {{-6.75, -7}, {-1.75, -7}, {-1.75, 7}, {10.25, 7}}, color = {1, 37, 163}));
  annotation(experiment(StopTime = 2.0, Interval = 0.1), Diagram(coordinateSystem(extent = {{-200, -200}, {200, 200}}, preserveAspectRatio = true, initialScale = 0.1, grid = {10, 10})), Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = false, initialScale = 0.1, grid = {10, 10})), Documentation(info = "<html>
<p>
A synchronous induction machine with permanent magnets accelerates a quadratic speed dependent load from standstill.
The rms values of d- and q-current in rotor fixed coordinate system are controlled by the voltageController,
and the output voltages fed to the machine. The result shows that the torque is influenced by the q-current,
whereas the stator voltage is influenced by the d-current.</p>
<p>
Default machine parameters of model <a href=\"modelica://Modelica.Electrical.Machines.BasicMachines.SynchronousInductionMachines.SM_PermanentMagnet\">SM_PermanentMagnet</a> are used.
</p>
</html>"));
end SMPM_INV_SineLoad;

And the signalPWM model:

model SignalPWM "Generates a pulse width modulated (PWM) boolean fire signal"
  extends Modelica.Electrical.PowerConverters.Icons.Control;
  parameter Boolean useConstantDutyCycle = true "Enables constant duty cycle";
  parameter Real constantDutyCycle = 0 "Constant duty cycle" annotation(Dialog(enable = useConstantDutyCycle));
  parameter Modelica.SIunits.Frequency f = 1000 "Switching frequency";
  parameter Modelica.SIunits.Time startTime = 0 "Start time";
  Modelica.Blocks.Interfaces.RealInput dutyCycle if not useConstantDutyCycle "Duty cycle" annotation(Placement(transformation(extent = {{-140, -20}, {-100, 20}})));
  Modelica.Blocks.Interfaces.BooleanOutput fire "Firing PWM signal" annotation(Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 90, origin = {-60, 110})));
  Modelica.Blocks.Interfaces.BooleanOutput notFire "Firing PWM signal" annotation(Placement(transformation(extent = {{-10, -10}, {10, 10}}, rotation = 90, origin = {60, 110})));
  Modelica.Blocks.Sources.Constant const(final k = constantDutyCycle) if useConstantDutyCycle annotation(Placement(transformation(extent = {{-100, -60}, {-80, -40}})));
  Modelica.Blocks.Nonlinear.Limiter limiter(uMax = 500000, uMin = -500000) annotation(Placement(transformation(extent = {{-60, -10}, {-40, 10}})));
  Modelica.Blocks.Logical.Less greaterEqual annotation(Placement(transformation(extent = {{-10, 10}, {10, -10}}, origin = {22, -8})));
  Modelica.Blocks.Discrete.ZeroOrderHold zeroOrderHold(final startTime = startTime, final samplePeriod = 1 / f) annotation(Placement(transformation(extent = {{-30, -10}, {-10, 10}})));
  Modelica.Blocks.Sources.SawTooth sawtooth(final period = 1 / f, final amplitude = 1000000, final nperiod = -1, final offset = -500000, final startTime = startTime) annotation(Placement(transformation(origin = {-50, -50}, extent = {{-10, -10}, {10, 10}})));
  Modelica.Blocks.Logical.Not inverse annotation(Placement(transformation(extent = {{-10, 10}, {10, -10}}, rotation = 90, origin = {52, 20})));
equation
  connect(const.y, limiter.u) annotation(Line(points = {{-79, -50}, {-70, -50}, {-70, 0}, {-62, 0}}, color = {0, 0, 127}));
  connect(dutyCycle, limiter.u) annotation(Line(points = {{-120, 0}, {-62, 0}}, color = {0, 0, 127}));
  connect(limiter.y, zeroOrderHold.u) annotation(Line(points = {{-39, 0}, {-32, 0}}, color = {0, 0, 127}));
  connect(zeroOrderHold.y, greaterEqual.u2) annotation(Line(points = {{-9, 0}, {10, 0}}, color = {0, 0, 127}));
  connect(sawtooth.y, greaterEqual.u1) annotation(Line(points = {{-39, -50}, {0, -50}, {0, -8}, {10, -8}}, color = {0, 0, 127}));
  connect(greaterEqual.y, inverse.u) annotation(Line(points = {{33, -8}, {52, -8}, {52, 8}}, color = {255, 0, 255}));
  connect(greaterEqual.y, fire) annotation(Line(points = {{33, -8}, {36, -8}, {36, 80}, {-60, 80}, {-60, 110}}, color = {255, 0, 255}));
  connect(inverse.y, notFire) annotation(Line(points = {{52, 31}, {52, 80}, {60, 80}, {60, 110}}, color = {255, 0, 255}));
  annotation(Icon(coordinateSystem(preserveAspectRatio = false, extent = {{-100, -100}, {100, 100}}, initialScale = 0.1, grid = {10, 10}), graphics = {Line(visible = true, points = {{-100, 0}, {-98, 0}, {12, 0}}, color = {64, 64, 64}), Line(visible = true, points = {{-60, -22}, {-60, -64}, {44, -64}, {44, -36}}, color = {64, 64, 64}), Line(visible = true, points = {{-80, -16}, {-80, -20}, {-40, 20}, {-40, -20}, {-36, -16}}, color = {64, 64, 64}), Line(visible = true, points = {{-62, 0}, {-76, 4}, {-76, -4}, {-62, 0}}, color = {64, 64, 64}), Line(visible = true, points = {{44, -36}, {44, -36}, {40, -50}, {44, -50}, {48, -50}, {44, -36}}, color = {64, 64, 64}), Line(visible = true, points = {{20, -20}, {22, -20}, {24, -20}, {24, 20}, {44, 20}, {44, -20}, {64, -20}, {64, -16}}, color = {190, 53, 179}), Line(visible = true, points = {{-40, -16}, {-40, -20}, {0, 20}, {0, -20}, {4, -16}}, color = {64, 64, 64}), Line(visible = true, points = {{60, -20}, {62, -20}, {64, -20}, {64, 20}, {84, 20}, {84, -20}, {84, -20}, {88, -20}}, color = {190, 53, 179})}), Documentation(info = "<html>
<p>
This controller can be used both for DC/DC and AC/DC converters.
The signal input of the PWM controller is the duty cycle; the duty cycle is the ratio of the on time
to the switching period. The output firing signal is strictly determined by the actual duty cycle, indicated as <code>d</code> in Fig.&nbsp;1.
</p>

<table border=\"0\" cellspacing=\"0\" cellpadding=\"2\">
  <caption align=\"bottom\"><b>Fig. 1:</b> Firing (<code>fire</code>) and inverse firing (<code>notFire</code>) signal of PWM control; <code>d</code> = duty cycle; <code>f</code> = switching frequency </caption>
  <tr>
    <td>
      <img src=\"modelica://Modelica/Resources/Images/Electrical/PowerConverters/dutyCycle.png\">
    </td>
  </tr>
</table>

<p>
The firing signal is generated by comparing the sampled duty cycle input with a periodic saw tooth signal [<a href=\"modelica://Modelica.Electrical.PowerConverters.UsersGuide.References\">Williams2006</a>].
</p>
</html>"));
end SignalPWM;

Edit: I already lowered the desired q-current from Idq={0,84} Ato Idq={0,10} A and the load from TLoad = 120 Nm to TLoad = 5 Nm and still get those insanely high voltage signals from the voltageController.

  • Has someone may an idea how to fix the problem with the controller so I get proper results for the simulation?
  • Why is it not able to reach the reference value as in the MSL example? Is the PWM block that big of a problem?
  • This behaviour of the simulation confuses me because I work with a real motor and a PWM control and it works fine with a similar configuration..

Any help would be highly appreciated!



Solution 1:[1]

Original Answer

With a voltage of ±200V and a load of 120Nm its simply not possible to obtain the demanded currents.

In contrast to the original MSL example you use a sign torque with 120Nm as load. If you use that in the original MSL example, you will notice that the machine keeps accelerating and that the required voltage grows without bounds (plot e.g. smpm.plug_sp.pin[1].v to see that).

In your example the voltage is limited to 200V. The demanded currents of -53A and 84.6A are not obtained, but the machine still generates a torque of 127Nm, which lets the machine accelerate. With increasing speed the required voltages increase also for a certain torque / current demand - but in your example the actual voltage is limited. Therefore the set currents are never reached.

What you can consider:

  • increase the available voltage
    (but for the current setup you need unrealistic high values of several thousand volts)
  • demand lower currents
    (You can set Id on 0 anyway, as you have a machine with Ld=Lq, so only Iq produces torque and Id is used for field weakening)
  • make your current controllers aware of the voltage limit
    (use e.g. Modelica.Blocks.Continuous.LimPID for that, which contains anti-windup already)

Updated Answer

The problem lies in your PWM computation. I rebuilt the example with the original SignalPWM block from the MSL and a VoltageToDutyCycle component.

In the screenshot below the simulation results of the new model with f=14kHz are compared with the MSL version with ideal voltage supply. The screenshot shows the controller output (like in your question) and Iq.

simulation results

The results were computed with the package below. It contains

  • a partial model for all common components and variables
  • an example with PWM and inverter
  • an example with ideal continuous voltage supply

Note that the hints from my original answer remain, if the maximum voltage is reached. The controllers are not aware of the voltage limit, which can lead to integrator windup problems.

package SMPM
  partial model SMPM_base "Test example: PermanentMagnetSynchronousInductionMachine fed by FOC"
    extends Modelica.Icons.Example;
    import Modelica.Constants.pi;
    constant Integer m=3 "Number of phases";
    parameter Modelica.SIunits.Frequency f=14000 "Switching frequency";
    parameter Modelica.SIunits.AngularVelocity wRef=30 "Desired speed of the PMSM";
    parameter Modelica.SIunits.Current Idq[2]={0,10} "Desired d- and q-current";
    parameter Modelica.SIunits.AngularVelocity wNominal=2*pi*smpmData.fsNominal/smpmData.p "Nominal speed";
    parameter Modelica.SIunits.Torque TLoad=5 "Nominal load torque";
    parameter Modelica.SIunits.Inertia JLoad=0.29 "Load's moment of inertia";
    parameter Modelica.SIunits.Voltage VBat_2=100 "Half Battery Voltage";
    final parameter Real Vmax=VBat_2*sqrt(2);
    Modelica.Electrical.Machines.BasicMachines.SynchronousInductionMachines.SM_PermanentMagnet smpm(
      phiMechanical(start=0, fixed=true),
      wMechanical(start=0, fixed=true),
      useSupport=false,
      useThermalPort=false,
      p=smpmData.p,
      fsNominal=smpmData.fsNominal,
      Rs=smpmData.Rs,
      TsRef=smpmData.TsRef,
      Lszero=smpmData.Lszero,
      Lssigma=smpmData.Lssigma,
      Jr=smpmData.Jr,
      Js=smpmData.Js,
      frictionParameters=smpmData.frictionParameters,
      statorCoreParameters=smpmData.statorCoreParameters,
      strayLoadParameters=smpmData.strayLoadParameters,
      VsOpenCircuit=smpmData.VsOpenCircuit,
      Lmd=smpmData.Lmd,
      Lmq=smpmData.Lmq,
      useDamperCage=smpmData.useDamperCage,
      Lrsigmad=smpmData.Lrsigmad,
      Lrsigmaq=smpmData.Lrsigmaq,
      Rrd=smpmData.Rrd,
      Rrq=smpmData.Rrq,
      TrRef=smpmData.TrRef,
      permanentMagnetLossParameters=smpmData.permanentMagnetLossParameters,
      TsOperational=293.15,
      alpha20s=smpmData.alpha20s,
      TrOperational=293.15,
      alpha20r=smpmData.alpha20r) annotation (Placement(transformation(
          extent={{-20,-50},{0,-30}},
          origin={40,-50},
          rotation=0), visible=true));
    Modelica.Electrical.Machines.Utilities.TerminalBox terminalBox(terminalConnection="Y") annotation (Placement(transformation(
          extent={{-20,-34},{0,-14}},
          origin={40,-50},
          rotation=0), visible=true));
    Modelica.Mechanics.Rotational.Sensors.AngleSensor angleSensor annotation (Placement(transformation(
          extent={{-10,-10},{10,10}},
          rotation=90,
          origin={60,-80}), visible=true));
    Modelica.Mechanics.Rotational.Components.Inertia inertiaLoad(J=JLoad) annotation (Placement(transformation(
          extent={{50,-50},{70,-30}},
          origin={60,-50},
          rotation=0), visible=true));
    Modelica.Electrical.MultiPhase.Sensors.CurrentSensor currentSensor(m=m) annotation (Placement(transformation(
          extent={{-10,-10},{10,10}},
          rotation=270,
          origin={30,-20}), visible=true));
    Modelica.Electrical.Machines.Utilities.VoltageController voltageController(
      p=smpm.p,
      Ld=smpm.Lssigma + smpm.Lmd,
      Lq=smpm.Lssigma + smpm.Lmq,
      Rs=Modelica.Electrical.Machines.Thermal.convertResistance(
          smpm.Rs,
          smpm.TsRef,
          smpm.alpha20s,
          smpm.TsOperational),
      fsNominal=smpm.fsNominal,
      VsOpenCircuit=smpm.VsOpenCircuit) annotation (Placement(transformation(
          extent={{-50,40},{-30,60}},
          origin={-60,-10},
          rotation=0), visible=true));
    Modelica.Mechanics.Rotational.Sensors.MultiSensor multiSensor annotation (Placement(transformation(
          extent={{10,10},{-10,-10}},
          rotation=180,
          origin={90,-90}), visible=true));
    Modelica.Electrical.Analog.Basic.Ground groundM annotation (Placement(transformation(
          origin={-60,-60},
          extent={{-10,-10},{10,10}},
          rotation=270), visible=true));
    Modelica.Electrical.MultiPhase.Basic.Star starM(final m=m) annotation (Placement(transformation(
          extent={{-10,-10},{10,10}},
          rotation=180,
          origin={-30,-60}), visible=true));
    Modelica.Electrical.Machines.Sensors.VoltageQuasiRMSSensor voltageQuasiRMSSensor annotation (Placement(transformation(
          extent={{-10,10},{10,-10}},
          rotation=180,
          origin={-10,-60}), visible=true));
    parameter Modelica.Electrical.Machines.Utilities.ParameterRecords.SM_PermanentMagnetData smpmData(useDamperCage=false)
      annotation (Placement(transformation(extent={{140,100},{160,120}}, rotation=0), visible=true));
    Modelica.Electrical.Machines.Sensors.CurrentQuasiRMSSensor currentQuasiRMSSensor annotation (Placement(transformation(
          origin={30,10},
          extent={{-10,-10},{10,10}},
          rotation=270), visible=true));
    Modelica.Mechanics.Rotational.Sources.SignTorque signTorque1(tau_constant=-TLoad, w0=wNominal) annotation (Placement(visible=true,
          transformation(
          origin={150,-90},
          extent={{10,-10},{-10,10}},
          rotation=0)));
    Modelica.Blocks.Sources.Constant id(k=Idq[1])
      annotation (Placement(transformation(extent={{-160,50},{-140,70}}, rotation=0), visible=true));
    Modelica.Blocks.Sources.Constant iq(k=Idq[2])
      annotation (Placement(transformation(extent={{-160,0},{-140,20}}, rotation=0), visible=true));
    Modelica.Electrical.MultiPhase.Sensors.VoltageSensor voltageSensor annotation (Placement(transformation(
          extent={{-10,10},{10,-10}},
          rotation=180,
          origin={-10,-88}), visible=true));
    Modelica.Blocks.Math.Mean meanVoltage(f=f/4) annotation (Placement(transformation(extent={{-30,-120},{-50,-100}})));
  initial equation 
    smpm.is[1:2] = zeros(2);
  equation 
    connect(terminalBox.plug_sn, smpm.plug_sn)
      annotation (Line(
        points={{24,-80},{24,-80}},
        color={0,0,255}));
    connect(terminalBox.plug_sp, smpm.plug_sp)
      annotation (Line(
        points={{0,0},{0,0}},
        color={0,0,255},
        origin={36,-80}));
    connect(starM.plug_p, voltageQuasiRMSSensor.plug_n)
      annotation (Line(
        points={{-50,-10},{-50,-10}},
        color={10,90,224},
        origin={30,-50}));
    connect(voltageSensor.plug_n, voltageQuasiRMSSensor.plug_n) annotation (Line(points={{-20,-88},{-20,-60}}, color={0,0,255}));
    connect(meanVoltage.u, voltageSensor.v[1]) annotation (Line(points={{-28,-110},{-10,-110},{-10,-98.3333}}, color={0,0,127}));
    connect(angleSensor.flange, smpm.flange) annotation (Line(points={{60,-90},{40,-90}}, color={0,0,0}));
    connect(smpm.flange, multiSensor.flange_a) annotation (Line(points={{40,-90},{80,-90}}, color={0,0,0}));
    connect(voltageController.phi, angleSensor.phi) annotation (Line(points={{-94,28},{-94,-6},{60,-6},{60,-69}}, color={0,0,127}));
    connect(id.y, voltageController.id_rms) annotation (Line(points={{-139,60},{-120,60},{-120,46},{-112,46}}, color={0,0,127}));
    connect(iq.y, voltageController.iq_rms) annotation (Line(points={{-139,10},{-120,10},{-120,34},{-112,34}}, color={0,0,127}));
    connect(voltageController.iActual, currentSensor.i) annotation (Line(points={{-106,28},{-106,-20},{19,-20}}, color={0,0,127}));
    connect(voltageQuasiRMSSensor.plug_p, terminalBox.plugSupply)
      annotation (Line(points={{0,-60},{30,-60},{30,-78}}, color={0,0,255}));
    connect(voltageSensor.plug_p, terminalBox.plugSupply)
      annotation (Line(points={{0,-88},{10,-88},{10,-60},{30,-60},{30,-78}}, color={0,0,255}));
    connect(currentSensor.plug_n, terminalBox.plugSupply) annotation (Line(points={{30,-30},{30,-78}}, color={0,0,255}));
    connect(multiSensor.flange_b, inertiaLoad.flange_a) annotation (Line(points={{100,-90},{110,-90}}, color={0,0,0}));
    connect(inertiaLoad.flange_b, signTorque1.flange) annotation (Line(points={{130,-90},{140,-90}}, color={0,0,0}));
    connect(starM.pin_n, groundM.p) annotation (Line(points={{-40,-60},{-50,-60}}, color={0,0,255}));
    connect(currentQuasiRMSSensor.plug_n, currentSensor.plug_p) annotation (Line(points={{30,0},{30,-10}}, color={0,0,255}));
    annotation (
      experiment(
        StopTime=0.2,
        Interval=0.00001,
        __Dymola_Algorithm="Dassl"),
      Diagram(coordinateSystem(extent={{-180,-140},{180,140}}, preserveAspectRatio=true)));
  end SMPM_base;

  model SMPM_PWM
    extends SMPM_base;
    Modelica.Electrical.PowerConverters.DCDC.Control.SignalPWM pwm[m](each useConstantDutyCycle=false, each f=f)
      annotation (Placement(visible=true, transformation(extent={{-20,30},{0,50}},   rotation=0)));
    Modelica.Electrical.PowerConverters.DCAC.MultiPhase2Level multiPhase2Level
      annotation (Placement(visible=true, transformation(extent={{-20,90},{0,110}},   rotation=0)));
    Modelica.Electrical.PowerConverters.DCDC.Control.VoltageToDutyCycle voltageToDutyCycle[3](
      each useBipolarVoltage=true,
      each useConstantMaximumVoltage=true,
      each vMax=VBat_2) annotation (Placement(transformation(extent={{-60,30},{-40,50}})));
    Modelica.Electrical.Analog.Sources.ConstantVoltage U_n(V=VBat_2) annotation (Placement(transformation(
          extent={{-10,-10},{10,10}},
          rotation=270,
          origin={-60,80}), visible=true));
    Modelica.Electrical.Analog.Basic.Ground ground annotation (Placement(transformation(
          extent={{-10,-10},{10,10}},
          rotation=270,
          origin={-80,100}),  visible=true));
    Modelica.Electrical.Analog.Sources.ConstantVoltage U_p(V=VBat_2) annotation (Placement(transformation(
          extent={{-10,-10},{10,10}},
          rotation=270,
          origin={-60,120}), visible=true));
    Modelica.Blocks.Math.Mean meanIq(f=f/4) annotation (Placement(transformation(extent={{-120,-60},{-140,-40}})));
  equation 
    connect(pwm[1:3].fire,multiPhase2Level. fire_p[1:3]) annotation (Line(
        visible=true,
        origin={-15.915,71.551},
        points={{-0.085,-20.551},{-0.085,17.7823}},
        color={190,52,178}));
    connect(pwm[1:3].notFire,multiPhase2Level. fire_n[1:3]) annotation (Line(
        visible=true,
        origin={-3.915,71.551},
        points={{-0.085,-20.551},{-0.085,17.7823}},
        color={190,52,178}));
    connect(U_p.p,multiPhase2Level. dc_p) annotation (Line(points={{-60,130},{-40,130},{-40,106},{-20,106}}, color={0,0,255}));
    connect(U_n.n,multiPhase2Level. dc_n) annotation (Line(points={{-60,70},{-40,70},{-40,94},{-20,94}}, color={0,0,255}));
    connect(voltageToDutyCycle.dutyCycle,pwm. dutyCycle) annotation (Line(points={{-39,40},{-22,40}}, color={0,0,127}));
    connect(multiPhase2Level.ac, currentQuasiRMSSensor.plug_p)
      annotation (Line(points={{0,100},{30,100},{30,20}},   color={0,0,255}));
    connect(voltageController.y,voltageToDutyCycle. v) annotation (Line(points={{-89,40},{-62,40}}, color={0,0,127}));
    connect(ground.p,U_n. p) annotation (Line(points={{-70,100},{-60,100},{-60,90}}, color={0,0,255}));
    connect(U_p.n,U_n. p) annotation (Line(points={{-60,110},{-60,90}}, color={0,0,255}));
    connect(meanIq.u, currentSensor.i[2]) annotation (Line(points={{-118,-50},{-106,-50},{-106,-20},{19,-20}}, color={0,0,127}));
    annotation (experiment(
        StopTime=0.2,
        Interval=0.00001,
        __Dymola_Algorithm="Dassl"));
  end SMPM_PWM;

  model SMPM_Continuous
    extends SMPM_base;
    Modelica.Electrical.MultiPhase.Basic.Star star(final m=m) annotation (
        Placement(transformation(extent={{10,-10},{-10,10}},
          rotation=270,
          origin={30,70})));
    Modelica.Electrical.Analog.Basic.Ground ground annotation (Placement(
          transformation(
          origin={30,100},
          extent={{-10,-10},{10,10}},
          rotation=180)));
    Modelica.Electrical.MultiPhase.Sources.SignalVoltage signalVoltage1(final m=m)
                   annotation (Placement(transformation(
          origin={30,40},
          extent={{10,10},{-10,-10}},
          rotation=270)));
  equation 
    connect(star.pin_n,ground. p)
      annotation (Line(points={{30,80},{30,90}},   color={0,0,255}));
    connect(star.plug_p, signalVoltage1.plug_n) annotation (Line(points={{30,60},{30,50}}, color={0,0,255}));
    connect(signalVoltage1.plug_p, currentQuasiRMSSensor.plug_p) annotation (Line(points={{30,30},{30,20}}, color={0,0,255}));
    connect(voltageController.y, signalVoltage1.v) annotation (Line(points={{-89,40},{18,40}}, color={0,0,127}));

    annotation (
      experiment(StopTime=0.2, __Dymola_Algorithm="Dassl"));
  end SMPM_Continuous;

  annotation(uses(Modelica(version="3.2.3")));
end SMPM;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1