Related
OpenModelica v1.17.0 (64-bit)
OMSimulator v2.0.0.post284-gc8ec782-mingw
Modelica Standard Library 3.2.3
Hello,
I'm currently working on the implementation of a dynamic model of a Stewart Platform in OpenModelica similar to the one in https://www.xarg.org/paper/inverse-kine … -platform/ (6RSS parallel robot) and apparently, I'm not able to connect multiple legs to the same platform due to the following error:
[1] 13:08:36 Translation Error
Internal error It is not possible to select continuous time states because Number of Equations 18 greater than number of States 17 to select from.
[2] 13:08:36 Translation Error
Internal error - IndexReduction.dynamicStateSelectionWork failed!
From what I have seen in the documentation of Modelica, this might be caused by some loop in the spanning tree generated during the translation phase of the model where some non-flow equations became dependent on each other resulting in an overconstrained (even if still solvable) system. It follows the source code of the package that I have created in which there are present a base, a platform, and only two RSS legs which create the issue.
package sixRSS_parallelRobot
model platform
import Modelica.SIunits;
import Modelica.Math;
constant SIunits.Length l = 0.7;
constant StateSelect stateSelect = StateSelect.prefer annotation(
Dialog(tab = "Advanced"));
final constant Real pi = 2 * Modelica.Math.asin(1.0);
parameter Boolean useQuat = false;
Modelica.Mechanics.MultiBody.Parts.Body body(enforceStates = stateSelect == StateSelect.always,m = 1, r_0(each fixed = true, start = {0, 0.5, 0}), r_CM = {0, 0, 0}, useQuaternions = useQuat, v_0(each fixed = true, start = {0, 0, 0}), w_a(each fixed = true)) annotation(
Placement(visible = true, transformation(origin = {70, 2}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation1(r = {l * cos(0 * (pi / 180) + (-5) * (pi / 180)), 0, l * sin(0 * (pi / 180) + (-5) * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-18, 68}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation2(r = {l * cos(0 * (pi / 180) + 5 * (pi / 180)), 0, l * sin(0 * (pi / 180) + 5 * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-14, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation3(r = {l * cos(120 * (pi / 180) + (-5) * (pi / 180)), 0, l * sin(120 * (pi / 180) + (-5) * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-18, 24}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation4(r = {l * cos(120 * (pi / 180) + 5 * (pi / 180)), 0, l * sin(120 * (pi / 180) + 5 * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-12, 2}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation5(r = {l * cos(240 * (pi / 180) + (-5) * (pi / 180)), 0, l * sin(240 * (pi / 180) + (-5) * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-14, -24}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
Modelica.Mechanics.MultiBody.Parts.FixedTranslation fixedTranslation6(r = {l * cos(240 * (pi / 180) + 5 * (pi / 180)), 0, l * sin(240 * (pi / 180) + 5 * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-16, -46}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
//outer Modelica.Mechanics.MultiBody.World world;
Modelica.Mechanics.MultiBody.Interfaces.Frame_b frame_b[6] annotation(
Placement(visible = true, transformation(origin = {-76, 10}, extent = {{-16, -16}, {16, 16}}, rotation = 0), iconTransformation(origin = {-100, 6}, extent = {{-16, -16}, {16, 16}}, rotation = 0)));
equation
connect(fixedTranslation1.frame_a, body.frame_a) annotation(
Line(points = {{-8, 68}, {30, 68}, {30, 2}, {60, 2}}, color = {95, 95, 95}));
connect(fixedTranslation2.frame_a, body.frame_a) annotation(
Line(points = {{-4, 50}, {30, 50}, {30, 2}, {60, 2}}, color = {95, 95, 95}));
connect(fixedTranslation3.frame_a, body.frame_a) annotation(
Line(points = {{-8, 24}, {30, 24}, {30, 2}, {60, 2}}));
connect(fixedTranslation4.frame_a, body.frame_a) annotation(
Line(points = {{-2, 2}, {60, 2}}));
connect(fixedTranslation5.frame_a, body.frame_a) annotation(
Line(points = {{-4, -24}, {30, -24}, {30, 2}, {60, 2}}, color = {95, 95, 95}));
connect(fixedTranslation6.frame_a, body.frame_a) annotation(
Line(points = {{-6, -46}, {30, -46}, {30, 2}, {60, 2}}, color = {95, 95, 95}));
connect(fixedTranslation2.frame_b, frame_b[2]) annotation(
Line(points = {{-24, 50}, {-56, 50}, {-56, 10}, {-76, 10}}, color = {95, 95, 95}));
connect(fixedTranslation3.frame_b, frame_b[3]) annotation(
Line(points = {{-28, 24}, {-56, 24}, {-56, 10}, {-76, 10}}, color = {95, 95, 95}));
connect(fixedTranslation4.frame_b, frame_b[4]) annotation(
Line(points = {{-22, 2}, {-56, 2}, {-56, 10}, {-76, 10}}, color = {95, 95, 95}));
connect(fixedTranslation5.frame_b, frame_b[5]) annotation(
Line(points = {{-24, -24}, {-56, -24}, {-56, 10}, {-76, 10}}, color = {95, 95, 95}));
connect(fixedTranslation6.frame_b, frame_b[6]) annotation(
Line(points = {{-26, -46}, {-56, -46}, {-56, 10}, {-76, 10}}, color = {95, 95, 95}));
connect(fixedTranslation1.frame_b, frame_b[1]) annotation(
Line(points = {{-28, 68}, {-56, 68}, {-56, 10}, {-76, 10}}, color = {95, 95, 95}));
annotation(
uses(Modelica(version = "3.2.3")));
end platform;
model base
import Modelica.SIunits;
import Modelica.Math;
constant SIunits.Length l = 0.7;
constant StateSelect stateSelect = StateSelect.prefer annotation(
Dialog(tab = "Advanced"));
final constant Real pi = 2 * Modelica.Math.asin(1.0);
parameter Boolean useQuat = false;
Modelica.Mechanics.MultiBody.Parts.Fixed fixed annotation(
Placement(visible = true, transformation(origin = {-16, 12}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.Fixed fixed1(r = {l * cos(0 * (pi / 180) + (-5) * (pi / 180)), 0, l * sin(0 * (pi / 180) + (-5) * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {54, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.Fixed fixed2(r = {l * cos(0 * (pi / 180) + 5 * (pi / 180)), 0, l * sin(0 * (pi / 180) + 5 * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {52, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.Fixed fixed3(r = {l * cos(120 * (pi / 180) + (-5) * (pi / 180)), 0, l * sin(120 * (pi / 180) + (-5) * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-46, 76}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.Fixed fixed4(r = {l * cos(120 * (pi / 180) + 5 * (pi / 180)), 0, l * sin(120 * (pi / 180) + 5 * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-74, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.Fixed fixed5(r = {l * cos(240 * (pi / 180) + (-5) * (pi / 180)), 0, l * sin(240 * (pi / 180) + (-5) * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-68, -26}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.Fixed fixed6(r = {l * cos(240 * (pi / 180) + 5 * (pi / 180)), 0, l * sin(240 * (pi / 180) + 5 * (pi / 180))}) annotation(
Placement(visible = true, transformation(origin = {-44, -68}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.Body body(enforceStates = stateSelect == StateSelect.always,m = 5, r_CM = {0, 0, 0}, useQuaternions = useQuat) annotation(
Placement(visible = true, transformation(origin = {12, 12}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
outer Modelica.Mechanics.MultiBody.World world;
Modelica.Mechanics.MultiBody.Interfaces.Frame_a frame_a[6] annotation(
Placement(visible = true, transformation(origin = {104, 16}, extent = {{-16, -16}, {16, 16}}, rotation = 0), iconTransformation(origin = {108, 0}, extent = {{-16, -16}, {16, 16}}, rotation = 0)));
equation
connect(fixed.frame_b, body.frame_a) annotation(
Line(points = {{-6, 12}, {2, 12}}, color = {95, 95, 95}));
connect(fixed1.frame_b, frame_a[1]) annotation(
Line(points = {{64, -2}, {86, -2}, {86, 16}, {104, 16}}));
connect(fixed2.frame_b, frame_a[2]) annotation(
Line(points = {{62, 30}, {86, 30}, {86, 16}, {104, 16}}, color = {95, 95, 95}));
connect(fixed3.frame_b, frame_a[3]) annotation(
Line(points = {{-36, 76}, {86, 76}, {86, 16}, {104, 16}}));
connect(fixed4.frame_b, frame_a[4]) annotation(
Line(points = {{-64, 50}, {86, 50}, {86, 16}, {104, 16}}));
connect(fixed5.frame_b, frame_a[5]) annotation(
Line(points = {{-58, -26}, {86, -26}, {86, 16}, {104, 16}}));
connect(fixed6.frame_b, frame_a[6]) annotation(
Line(points = {{-34, -68}, {86, -68}, {86, 16}, {104, 16}}));
annotation(
uses(Modelica(version = "3.2.3")));
end base;
model fullmodel
inner Modelica.Mechanics.MultiBody.World world annotation(
Placement(visible = true, transformation(origin = {-68, 14}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
sixRSS_parallelRobot.platform platform(useQuat = true) annotation(
Placement(visible = true, transformation(origin = {106, 12}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
sixRSS_parallelRobot.base base(useQuat = true) annotation(
Placement(visible = true, transformation(origin = {-26, 14}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Joints.Revolute revolute(n = {1, 0, 0}, phi(displayUnit = "rad")) annotation(
Placement(visible = true, transformation(origin = {-1, 29}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.BodyShape bodyShape(m = 0.01, r = {0, 0, -0.2}, r_CM = {0, 0, -0.1}) annotation(
Placement(visible = true, transformation(origin = {19, 29}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Joints.Spherical spherical annotation(
Placement(visible = true, transformation(origin = {35, 29}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.BodyShape bodyShape1(m = 0.002, r = {0, 0.5, 0.2}, r_CM = {0, 0.25, 0.1}) annotation(
Placement(visible = true, transformation(origin = {51, 29}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Joints.Spherical spherical1 annotation(
Placement(visible = true, transformation(origin = {71, 29}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Joints.Revolute revolute1(n = {1, 0, 0}, phi(displayUnit = "rad")) annotation(
Placement(visible = true, transformation(origin = {1, -1}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.BodyShape bodyShape2(m = 0.01, r = {0, 0, 0.2}, r_CM = {0, 0, 0.1}) annotation(
Placement(visible = true, transformation(origin = {21, -1}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Joints.Spherical spherical2 annotation(
Placement(visible = true, transformation(origin = {37, -1}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Parts.BodyShape bodyShape3(m = 0.002, r = {0, 0.5, -0.2}, r_CM = {0, 0.25, -0.1}) annotation(
Placement(visible = true, transformation(origin = {53, -1}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
Modelica.Mechanics.MultiBody.Joints.Spherical spherical3 annotation(
Placement(visible = true, transformation(origin = {73, -1}, extent = {{-7, -7}, {7, 7}}, rotation = 0)));
equation
connect(revolute.frame_b, bodyShape.frame_a) annotation(
Line(points = {{6, 29}, {12, 29}}));
connect(bodyShape.frame_b, spherical.frame_a) annotation(
Line(points = {{26, 29}, {28, 29}}, color = {95, 95, 95}));
connect(spherical.frame_b, bodyShape1.frame_a) annotation(
Line(points = {{42, 29}, {44, 29}}, color = {95, 95, 95}));
connect(bodyShape1.frame_b, spherical1.frame_a) annotation(
Line(points = {{58, 30}, {64, 30}}));
connect(revolute.frame_a, base.frame_a[1]) annotation(
Line(points = {{-8, 30}, {-10, 30}, {-10, 14}, {-16, 14}}));
connect(spherical1.frame_b, platform.frame_b[1]) annotation(
Line(points = {{78, 30}, {88, 30}, {88, 12}, {96, 12}}, color = {95, 95, 95}));
connect(base.frame_a[2], revolute1.frame_a) annotation(
Line(points = {{-16, 14}, {-10, 14}, {-10, 0}, {-6, 0}}, color = {95, 95, 95}));
connect(revolute1.frame_b, bodyShape2.frame_a) annotation(
Line(points = {{8, 0}, {14, 0}}, color = {95, 95, 95}));
connect(bodyShape2.frame_b, spherical2.frame_a) annotation(
Line(points = {{28, 0}, {30, 0}}, color = {95, 95, 95}));
connect(spherical2.frame_b, bodyShape3.frame_a) annotation(
Line(points = {{44, 0}, {46, 0}}, color = {95, 95, 95}));
connect(bodyShape3.frame_b, spherical3.frame_a) annotation(
Line(points = {{60, 0}, {66, 0}}));
connect(spherical3.frame_b, platform.frame_b[2]) annotation(
Line(points = {{80, 0}, {88, 0}, {88, 12}, {96, 12}}));
end fullmodel;
annotation(
uses(Modelica(version = "3.2.3")));
end sixRSS_parallelRobot;
Since I'm new to Modelica, I think I'm missing some basic concepts of modelling multibody mechanics especially when kinematics loops take place. I've already made some tests on the planar loop fourbar example in the Modelica library but I think this is something different. Is there a way to solve this error and finally obtain a working model of the 6RSS parallel robot?
Thank you in advance for your help!
Not actually an answer, I know, but with a comment only, adding the gif below wouldn't be possible.
The model works in Dymola 2022 (after converting to MSL 4.0.0) and Dymola 2020x (with MSL 3.2.3) without any important warning. So, given the result below is what you would expect, then there is no fundamental error within the model. The resulting animation looks like this:
Dymola does dynamic state selection for the model - I'm not sure whether OpenModelica is able to do that as well. Generally I can't really help with OpenModelica unfortunately. But Probably this is already of help for you...
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:
and the current output:
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 SM_PermanentMagnet 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. 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 [Williams2006].
</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!
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.
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;
I'm using the realFFT library with OpenModelica to analyze the frequencies in a PWM signal.
When I analyze frequencies below 10 kHz everything works fine.
But as soon as I set my maximum frequency to more than 10 kHz my simulation either calculates wrong results, crashes or says that it simulated but doesn't show the results.
What I found out so far:
I have a the samplePeriod=8.3us and the number of samples ns=6000 for a max frequency of f_max=12kHz and a resolution of f_res=20Hz which results in a stopTime>=(6000-1)*8.3us --> stopTime>=0.05s (according to the library).
So I simulated with this stopTime and it worked but when I set stopTime=0.1s it doesn't show any results but says that it simulated fine. When I further increased the stopTime to 0.2s it calculated wrong results.
This doesn't make sense to me, why should it fail with an increased stopTime?
Might this be another OpenModelica issue and works fine with Dymola?
Here are my models:
model TestRealFFT
Modelica.Blocks.Sources.Pulse pulse1(amplitude = 1, offset = 0, period = 100e-6, width = 40) annotation(
Placement(visible = true, transformation(origin = {-168, 16}, extent = {{-60, -60}, {60, 60}}, rotation = 0)));
FFTmath fFTmath1(f_max = 12000, f_res = 20) annotation(
Placement(visible = true, transformation(origin = {176, 8}, extent = {{-80, -80}, {80, 80}}, rotation = 0)));
equation
connect(pulse1.y, fFTmath1.u) annotation(
Line(points = {{-102, 16}, {68, 16}, {68, 8}, {80, 8}}, color = {0, 0, 127}));
annotation(
stopTime = 2,
Diagram(coordinateSystem(extent = {{-300, -250}, {300, 250}})),
Icon(coordinateSystem(extent = {{-300, -250}, {300, 250}})),
__OpenModelica_commandLineOptions = "",
experiment(StartTime = 0, StopTime = 0.2, Tolerance = 1e-06, Interval = 8e-06));
end TestRealFFT;
and
model FFTmath
import Modelica.Constants.{pi};
import Modelica.Math.FastFourierTransform.*;
import Modelica.SIunits.*;
Modelica.Blocks.Interfaces.RealInput u annotation(
Placement(visible = true, transformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
parameter Frequency f_max = 12000 "Maximum frequency of interest";
parameter Frequency f_res = 20 "Frequency resolution";
final parameter Integer ns = realFFTsamplePoints(f_max, f_res, f_max_factor = 5) "Number of samples";
final parameter Integer nf = div(ns, 2) + 1 "Number of frequency points";
final parameter Integer nfi = max(1, min(integer(ceil(f_max / f_res)) + 1, nf));
final parameter Frequency f_i[nfi](each fixed = false) "FFT frequencies of interested frequency points";
parameter Time samplePeriod = 1 / (2 * f_res * div(ns, 2));
output Integer info(start = 0, fixed = true) "Information flag from FFT computation";
Integer iTick(start = 0, fixed = true);
discrete Real Buf[ns](start = zeros(ns), each fixed = true) "Input buffer";
Real A_i[nfi](start = zeros(nfi), each fixed = true) "FFT amplitudes";
Real Phi_i[nfi](start = zeros(nfi), each fixed = true) "FFT phases";
Real y(start = 0, fixed = true);
// "Signal from which FFT is computed";
initial equation
for i in 1:nfi loop
f_i[i] = (i - 1) * f_res;
end for;
equation
algorithm
when sample(0, samplePeriod) then
iTick := iTick + 1;
y := u;
if iTick <= ns then
Buf[iTick] := y;
end if;
if iTick == ns then
(info, A_i, Phi_i) := realFFT(Buf, nfi);
end if;
end when;
//3 * sin(2 * pi * f1 * time) + sin(2 * pi * f2 * time);
annotation(
Documentation(Icon(graphics = {Text(origin = {-42, 62}, extent = {{110, -78}, {-30, 18}}, textString = "FFT"), Rectangle(origin = {0, -79}, fillPattern = FillPattern.Solid, extent = {{-80, -1}, {80, 1}}), Rectangle(origin = {-79, -49}, fillPattern = FillPattern.Solid, extent = {{-1, -29}, {1, 29}}), Polygon(origin = {-79, -15}, fillPattern = FillPattern.Solid, points = {{0, -5}, {-6, -5}, {0, 5}, {6, -5}, {6, -5}, {0, -5}}), Polygon(origin = {85, -79}, rotation = -90, fillPattern = FillPattern.Solid, points = {{0, -5}, {-6, -5}, {0, 5}, {6, -5}, {6, -5}, {0, -5}}), Rectangle(origin = {-59, -65}, fillPattern = FillPattern.Solid, extent = {{-1, 23}, {1, -15}}), Ellipse(origin = {-59, -39}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-49, -61}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-19, -53}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {25, -67}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {31, -49}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Rectangle(origin = {-49, -65}, fillPattern = FillPattern.Solid, extent = {{-1, 1}, {1, -15}}), Rectangle(origin = {31, -65}, fillPattern = FillPattern.Solid, extent = {{-1, 15}, {1, -15}}), Rectangle(origin = {-19, -63}, fillPattern = FillPattern.Solid, extent = {{-1, 7}, {1, -15}}), Rectangle(origin = {25, -63}, fillPattern = FillPattern.Solid, extent = {{-1, -5}, {1, -15}}), Ellipse(origin = {-67, -61}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Rectangle(origin = {-67, -63}, fillPattern = FillPattern.Solid, extent = {{-1, 1}, {1, -15}}), Rectangle(origin = {37, -63}, fillPattern = FillPattern.Solid, extent = {{-1, -5}, {1, -15}}), Ellipse(origin = {37, -67}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Line(points = {{-100, 100}, {100, 100}, {100, -100}, {-100, -100}, {-100, 100}, {-100, 100}}, thickness = 0.5)}),
Diagram,
__OpenModelica_commandLineOptions = "");
end FFTmath;
I'm very thankful for any help!
Looks like a bug in OpenModelica. Please open a ticket about it on trac.openmodelica.org.
Problem 1 Huge result files are breaking
When simulating with OpenModelica (v1.14.0-dev-26633-gd9901afc5b) for 0.05 sec simulation time the result mat-file is already 1.06 GB. For 0.1 sec you get around 2.1 GB and a corrupt header.
Problem 2 Wrong results
When you simulate interval [0, 0.2] the solution is completely wrong. Values of y are somewhere around 1.4e+31 and time goes up to 5e+218. Could be because of the broken result file.
But even if you reduce tolerance and interval it won't simulate correctly, maybe because of the huge amount of events.
Works in Dymola 2019, but needs a lot of time to open the result files.
I am trying to model and replicate the "Open Brayton Power Cycle" from the OpenModelica Library and have come across an error message that makes little sense. The error message is the result of incompatibility between sourceMassflow.mo and CombustionChamber.mo, all taken from the modelica library and connected in the same fashion as the library Brayton example has been done.
This error has occurred after completely replicating the "Brayton Power Cycle - Open" from the modelica library.
This is the error I am receiving. This message almost proves that the two components are compatible with one another however I cannot figure out the reason why they are "not working" together.
[11] 14:18:40 Translation Error
[BraytonCycle_First: 49:3-50:84]: Incompatible components in connect statement: connect(sourceMassFlow1.flange, combustionChamber1.inf)
- sourceMassFlow1.flange has components {C_outflow, Xi_outflow, h_outflow, m_flow, p}
- combustionChamber1.inf has components {C_outflow, Xi_outflow, h_outflow, m_flow, p}
I copied all of the library's component parameters into my model and expected this to solve the issue. Nothing I have done fixes this issue, where it seems that these models would be compatible due to the error message above.
Any help or advice would be greatly appreciated.
This model compiles but has issues with simulation. Maybe you can fix those. I changed all the redeclares to use ThermoPower.Media.* mediums.
model BraytonCycleLibraryReplica "Brayton Cycle iterations with re-declared mediums and copied values from Library Plant"
//Figure out the importance of table values//
parameter Real tableEtaC[6, 4]=[0, 95, 100, 105; 1, 82.5e-2, 81e-2,
80.5e-2; 2, 84e-2, 82.9e-2, 82e-2; 3, 83.2e-2, 82.2e-2, 81.5e-2; 4,
82.5e-2, 81.2e-2, 79e-2; 5, 79.5e-2, 78e-2, 76.5e-2];
parameter Real tablePhicC[6, 4]=[0, 95, 100, 105; 1, 38.3e-3, 43e-3,
46.8e-3; 2, 39.3e-3, 43.8e-3, 47.9e-3; 3, 40.6e-3, 45.2e-3, 48.4e-3;
4, 41.6e-3, 46.1e-3, 48.9e-3; 5, 42.3e-3, 46.6e-3, 49.3e-3];
parameter Real tablePR[6, 4]=[0, 95, 100, 105; 1, 22.6, 27, 32; 2, 22,
26.6, 30.8; 3, 20.8, 25.5, 29; 4, 19, 24.3, 27.1; 5, 17, 21.5, 24.2];
parameter Real tablePhicT[5, 4]=[1, 90, 100, 110; 2.36, 4.68e-3, 4.68e-3,
4.68e-3; 2.88, 4.68e-3, 4.68e-3, 4.68e-3; 3.56, 4.68e-3, 4.68e-3,
4.68e-3; 4.46, 4.68e-3, 4.68e-3, 4.68e-3];
parameter Real tableEtaT[5, 4]=[1, 90, 100, 110; 2.36, 89e-2, 89.5e-2,
89.3e-2; 2.88, 90e-2, 90.6e-2, 90.5e-2; 3.56, 90.5e-2, 90.6e-2,
90.5e-2; 4.46, 90.2e-2, 90.3e-2, 90e-2];
ThermoPower.Gas.Turbine turbine1(
redeclare package Medium = ThermoPower.Media.FlueGas,
Ndesign = 157.08,
Table = ThermoPower.Choices.TurboMachinery.TableTypes.matrix,
Tdes_in = 1400,
Tstart_in = 1370,
Tstart_out = 800,
pstart_in = 7.85e5,
pstart_out = 1.52e5, tableEta = tableEtaT, tablePhic = tablePhicT)
annotation(
Placement(visible = true, transformation(origin = {40, -8}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
ThermoPower.Gas.Compressor compressor1(
redeclare package Medium = ThermoPower.Media.Air,
Ndesign = 157.08,
Table = ThermoPower.Choices.TurboMachinery.TableTypes.matrix,
Tdes_in = 244.4,
Tstart_in = 244.4,
Tstart_out = 600.4,
explicitIsentropicEnthalpy = true,
pstart_in = 0.343e5,
pstart_out = 8.3e5, tableEta = tableEtaC, tablePR = tablePR, tablePhic = tablePhicC)
annotation(
Placement(visible = true, transformation(origin = {-40, -8}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
ThermoPower.Gas.CombustionChamber combustionChamber1(
Cm = 1,
HH = 41.6e6,
S = 0.05,
Tstart = 1370,
V = 0.05,
gamma = 1,
initOpt = ThermoPower.Choices.Init.Options.steadyState,
pstart = 8.11e5)
annotation(
Placement(visible = true, transformation(origin = {0, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
ThermoPower.Gas.PressDrop pressDrop1(
redeclare package Medium = ThermoPower.Media.Air, A = 1, FFtype = ThermoPower.Choices.PressDrop.FFtypes.OpPoint, Tstart = 600, dpnom = 19000, pstart = 8.3e5, rhonom = 4.7, wnom = 100)
annotation(
Placement(visible = true, transformation(origin = {-32, 14}, extent = {{-6, -6}, {6, 6}}, rotation = -90)));
ThermoPower.Gas.PressDrop pressDrop2(
redeclare package Medium = ThermoPower.Media.FlueGas,
FFtype = ThermoPower.Choices.PressDrop.FFtypes.OpPoint,
Tstart = 1370,
dpnom = 26000,
pstart = 811000,
rhonom = 2,
wnom = 102)
annotation(
Placement(visible = true, transformation(origin = {32, 14}, extent = {{-6, -6}, {6, 6}}, rotation = -90)));
ThermoPower.Gas.SourceMassFlow sourceMassFlow1(
redeclare package Medium = ThermoPower.Media.NaturalGas, T = 300, p0 = 811000, use_in_w0 = true, w0 = 2.02)
annotation(
Placement(visible = true, transformation(origin = {-44, 40}, extent = {{-6, -6}, {6, 6}}, rotation = 0)));
ThermoPower.Gas.SourcePressure sourcePressure1(
redeclare package Medium = ThermoPower.Media.Air,
T = 244.4,
p0 = 34300)
annotation(
Placement(visible = true, transformation(origin = {-92, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
ThermoPower.PowerPlants.HRSG.Components.StateReader_gas stateReader_gas1(
redeclare package Medium = ThermoPower.Media.Air)
annotation(
Placement(visible = true, transformation(origin = {-22, 30}, extent = {{-8, -8}, {8, 8}}, rotation = 0)));
ThermoPower.PowerPlants.HRSG.Components.StateReader_gas stateReader_gas2(
redeclare package Medium = ThermoPower.Media.FlueGas)
annotation(
Placement(visible = true, transformation(origin = {22, 30}, extent = {{-8, -8}, {8, 8}}, rotation = 0)));
Modelica.Blocks.Continuous.FirstOrder firstOrder1(
T = 4,
initType = Modelica.Blocks.Types.Init.SteadyState,
y_start = 500)
annotation(
Placement(visible = true, transformation(origin = {-85, 51}, extent = {{-5, -5}, {5, 5}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealInput FuelFlowRate
annotation(
Placement(visible = true, transformation(origin = {-142, 18}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-142, 18}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
ThermoPower.Gas.SinkPressure sinkPressure1(
redeclare package Medium = ThermoPower.Media.FlueGas,
T = 800,
p0 = 1.52e5)
annotation(
Placement(visible = true, transformation(origin = {66, 20}, extent = {{-6, -6}, {6, 6}}, rotation = 0)));
Modelica.Mechanics.Rotational.Sensors.PowerSensor powerSensor1
annotation(
Placement(visible = true, transformation(origin = {60, -8}, extent = {{-6, -6}, {6, 6}}, rotation = 0)));
ThermoPower.Electrical.Generator generator1(
J = 30,
initOpt = ThermoPower.Choices.Init.Options.steadyState,
shaft(phi(start=0, fixed=true)))
annotation(
Placement(visible = true, transformation(origin = {80, -8}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Continuous.FirstOrder firstOrder2(
T = 1,
initType = Modelica.Blocks.Types.Init.SteadyState,
k = 1,
y_start = 56.8e6)
annotation(
Placement(visible = true, transformation(origin = {80, -36}, extent = {{-6, -6}, {6, 6}}, rotation = 0)));
Modelica.Blocks.Interfaces.RealOutput GeneratedPower
annotation(
Placement(visible = true, transformation(origin = {106, 16}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {106, 16}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
ThermoPower.Electrical.NetworkGrid_Pmax networkGrid_Pmax1(
J = 30000,
Pmax = 10e6,
deltaStart = 0.4,
initOpt = ThermoPower.Choices.Init.Options.steadyState)
annotation(
Placement(visible = true, transformation(origin = {106, -8}, extent = {{-8, -8}, {8, 8}}, rotation = 0)));
inner ThermoPower.System system annotation(
Placement(visible = true, transformation(origin = {-130, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
connect(firstOrder2.y, GeneratedPower) annotation(
Line(points = {{86, -36}, {92, -36}, {92, 16}, {106, 16}, {106, 16}}, color = {0, 0, 127}));
connect(powerSensor1.power, firstOrder2.u) annotation(
Line(points = {{56, -14}, {56, -36}, {73, -36}}, color = {0, 0, 127}));
connect(powerSensor1.flange_b, generator1.shaft) annotation(
Line(points = {{66, -8}, {72, -8}, {72, -8}, {72, -8}}));
connect(turbine1.shaft_b, powerSensor1.flange_a) annotation(
Line(points = {{46, -8}, {54, -8}, {54, -8}, {54, -8}, {54, -8}}));
connect(turbine1.outlet, sinkPressure1.flange) annotation(
Line(points = {{48, 0}, {48, 0}, {48, 20}, {60, 20}, {60, 20}}, color = {159, 159, 223}));
connect(sourcePressure1.flange, compressor1.inlet) annotation(
Line(points = {{-82, 0}, {-48, 0}, {-48, 0}, {-48, 0}}, color = {159, 159, 223}));
connect(firstOrder1.y, sourceMassFlow1.in_w0) annotation(
Line(points = {{-80, 52}, {-48, 52}, {-48, 44}, {-48, 44}, {-48, 44}}, color = {0, 0, 127}));
connect(sourceMassFlow1.flange, combustionChamber1.inf) annotation(
Line(points = {{-38, 40}, {0, 40}, {0, 40}, {0, 40}}, color = {159, 159, 223}));
connect(FuelFlowRate, firstOrder1.u) annotation(
Line(points = {{-142, 18}, {-100, 18}, {-100, 51}, {-91, 51}}, color = {0, 0, 127}));
connect(pressDrop2.outlet, turbine1.inlet) annotation(
Line(points = {{32, 8}, {32, 8}, {32, 0}, {32, 0}}, color = {159, 159, 223}));
connect(pressDrop1.outlet, compressor1.outlet) annotation(
Line(points = {{-32, 8}, {-32, 8}, {-32, 0}, {-32, 0}}, color = {159, 159, 223}));
connect(stateReader_gas2.outlet, pressDrop2.inlet) annotation(
Line(points = {{26, 30}, {32, 30}, {32, 20}, {32, 20}}, color = {159, 159, 223}));
connect(combustionChamber1.out, stateReader_gas2.inlet) annotation(
Line(points = {{10, 30}, {18, 30}, {18, 30}, {18, 30}}, color = {159, 159, 223}));
connect(stateReader_gas1.outlet, combustionChamber1.ina) annotation(
Line(points = {{-18, 30}, {-10, 30}, {-10, 30}, {-10, 30}}, color = {159, 159, 223}));
connect(pressDrop1.inlet, stateReader_gas1.inlet) annotation(
Line(points = {{-32, 20}, {-32, 20}, {-32, 30}, {-26, 30}, {-26, 30}}, color = {159, 159, 223}));
connect(compressor1.shaft_b, turbine1.shaft_a) annotation(
Line(points = {{-34, -8}, {34, -8}}));
annotation(
uses(ThermoPower(version = "3.1"), Modelica(version = "3.2.2")));
end BraytonCycleLibraryReplica;
I am trying to simulate the flow in a pipe that starts out partially full, and gradually fills up. Once it is full, the flow equation needs to change. I have tried the following code, but I get a divide by zero error once the pipe is full. TestTrap1 is a demo that shows the problem. It seems that some equation is not correct once the pipe is full.
I am using openmodelica to run this.
package FlowPackage
package Interfaces
extends Modelica.Icons.InterfacesPackage;
//Use this for a inlet outlet device
connector Fitting "Inlet port"
flow Modelica.SIunits.MassFlowRate q "Flow rate [Kg/s]";
Modelica.SIunits.Pressure P "Pressure";
annotation(defaultComponentName = "fitting", Icon(coordinateSystem(preserveAspectRatio = true, extent = {{-100, -100}, {100, 100}}), graphics = {Rectangle(extent = {{-100, 100}, {100, -100}}, lineColor = {0, 0, 255}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid)}), Diagram(coordinateSystem(preserveAspectRatio = true, extent = {{-100, -100}, {100, 100}}), graphics = {Rectangle(extent = {{-40, 40}, {40, -40}}, lineColor = {0, 0, 255}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid), Text(extent = {{-160, 110}, {40, 50}}, lineColor = {0, 0, 255}, textString = "%name")}));
end Fitting;
end Interfaces;
model SourceConstant
parameter Modelica.SIunits.MassFlowRate q = 0.015 "Flow rate [Kg/s]";
Interfaces.Fitting fitting annotation(Placement(visible = true, transformation(origin = {100, -6}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, -6}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
-fitting.q = q;
annotation(Icon(graphics = {Rectangle(origin = {-3, 30}, extent = {{-93, 60}, {93, -60}}), Rectangle(origin = {0, 15}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-90, 45}, {90, -45}})}), Diagram);
end SourceConstant;
model ZeroP
parameter Modelica.SIunits.Pressure p = 0.00 "Pressure";
Interfaces.Fitting fitting annotation(Placement(visible = true, transformation(origin = {100, -6}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, -6}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
fitting.P = p;
annotation(Icon(graphics = {Rectangle(origin = {-1, 2}, extent = {{-95, 94}, {95, -94}})}), Diagram);
end ZeroP;
model TestTrap1
TrapTemp trap1 ( level(start = 0.0509)) annotation(Placement(visible = true, transformation(origin = {10, 8}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
SourceConstant sourceConstant1(q = 0.03) annotation(Placement(visible = true, transformation(origin = {-50, 26}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
ZeroP zeroP1 (p = 101000) annotation(Placement(visible = true, transformation(origin = {64, 8}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
equation
connect(sourceConstant1.fitting, trap1.fitting_in) annotation(Line(points = {{-40, 26}, {-18, 26}, {-18, 8}, {0, 8}, {0, 8}}, color = {0, 0, 255}));
connect(trap1.fitting_out, zeroP1.fitting) annotation(Line(points = {{20, 8}, {54, 8}, {54, 8}, {54, 8}}, color = {0, 0, 255}));
annotation(Icon, Diagram, experiment(StartTime = 0, StopTime = 1450, Tolerance = 1e-6, Interval = 2.9));
end TestTrap1;
model TrapTemp
//Calculate the velocity for pipe segments
Interfaces.Fitting fitting_in annotation(Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Interfaces.Fitting fitting_out annotation(Placement(visible = true, transformation(origin = {98, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {98, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
import m = Modelica.Math;
parameter Modelica.SIunits.Length L = 25000 "pipe length (m)";
parameter Modelica.SIunits.Radius R = 0.10194 / 2.0 "pipe inner radius (m)";
parameter Modelica.SIunits.Height roughness = 6.0e-5 "Average height of surface asperities (default: smooth steel pipe)";
/*Values below are liquid at 300K*/
parameter Modelica.SIunits.DynamicViscosity mu = 0.092977 "Dynamic Viscocity (cp)";
parameter Modelica.SIunits.Density row = 501.22 "Density (kg/m^3)";
Modelica.SIunits.Area A;
Modelica.SIunits.Length s(start = 0.158) "wetted perimeter";
Modelica.SIunits.Length rh "hydraulic radius";
Modelica.SIunits.Diameter De(start = 0.1) "eqivalent diameter [m]";
Modelica.SIunits.ReynoldsNumber Re(start = 3000);
Modelica.SIunits.Velocity v(start = 0.0001);
Modelica.SIunits.Length hf "Friction head loss";
Modelica.SIunits.Acceleration g = Modelica.Constants.g_n;
Modelica.SIunits.Acceleration a "Acceleration of flow";
Modelica.SIunits.CoefficientOfFriction f;
Real relative_roughness;
Real percent_full "Fraction of pipe is full [%]";
Modelica.SIunits.Mass mass;
Real percent_full "Fraction of pipe is full [%]";
Modelica.SIunits.Height level "Liquid level (m)";
equation
percent_full = level / R * 100.0;
relative_roughness = roughness / De;
a = der(v);
s = 2 * level + R;
rh = A / s;
De = 4 * rh;
//Protect against negative Re:
Re = De * abs(v) * row / mu;
//Head loss due to friction. Corrected for direction
hf = sign(v) * f * L * v ^ 2 / (2 * De * g);
f = 64 / Re ;
mass = A * row * L;
fitting_in.q + fitting_out.q = der(mass);
fitting_out.q = -v * A * row;
mass * a = A * (fitting_in.P - fitting_out.P - hf * row * g ) ;
A = R * level;
if noEvent(level >= R) then
//full pipe
fitting_in.q = -fitting_out.q;
else
//partially full pipe
fitting_in.P = fitting_out.P;
end if;
annotation(Icon, Diagram);
end TrapTemp;
annotation(Icon, Diagram);
end FlowPackage;
Any suggestions about why this doesn't work, or how to fix it would be greatly appreciated.
firstly, you need to define what is what you want, I mean, if you want to start storing fluid within the pipe before transferring it, you need to define the set of mass and energy equations to store liquid, i.e: if you want to store liquid you cannot calculate Re, because v=0, and once is filled, swap the model as you did with one conditional and define the navier-stokes equations to define the momentum of the fluid.
Anyway, I think you should try connecting one mass flow rate source, one tank, one valve (define the opening law for the valve in function of the level of the tank), one pipe and one sink with the Modelica Standard library components.