# Avoid problem with for- and when-loops for finding table values in SM?

Posted 1 year ago
1408 Views
|
3 Replies
|
1 Total Likes
|
 Hi,Edited: formatted code snippetI am trying to write a model that will find be the suitable shaft speed of my machine based in a reference input signal. I want to search the table for the threshold value of the reference input and find the corresponding shaft speed. I do not want to interpolate so CombiTimeTable is not a good choice.The table length (always two columns) is arbitrary and I do want the code to be as simple as possible. I therefore started with a for-loop stepping through the table. If then use a when-loop to define my event. An if-loop does not work, won't compile (I do not know why).Now, when I test my model giving both constant Real as input and Real ramp the model works fine and does exactly what I expect it to do. However, when I insert my model into the complete system model, it does nothing. Input is now Real constant, but the model outputs only the value zero (which is not even in the table...).Anyone with any idea on what might be wrong?Code below: model RefIntoSpeedConversionTest "Sets shaft speed from reference input level" Modelica.Blocks.Interfaces.RealInput RefIn; discrete Modelica.Blocks.Interfaces.RealOutput RPM; parameter Real speedtable[:, :] = [0, 1200; 200, 1200; 380, 1200; 450, 1400; 550, 1600; 650, 1800; 750, 1950; 850, 2100; 1000, 2100; 1200, 2100] ; parameter Integer length = size(speedtable, 1) - 1; algorithm for i in 1:length loop when speedtable[i, 1] <= RefIn and RefIn < speedtable[i + 1, 1] then RPM := speedtable[i, 2]; end when; end for; end RefIntoSpeedConversionTest; Regards,Martin
3 Replies
Sort By:
Posted 1 year ago
 Hi Martin!Your model does not have anything that specifies the initial output from the block. When statements only update the output when an event happens (your input crosses over a certain value in your case). If your input is constant, no event will occur. Since there is nothing that forces the output to start at a specific value, the solver will make a qualified guess. If nothing is connected to the output it chooses the table value. If something is connected in to the output, say a Modelica.Mechanics.Rotational.Sources.Speed it will have its own preferred initialization value, in most cases 0. So out of those two conflicting initialization, the solver chooses the 0 value, and then it stays at that value since no event happens.You could write add the "initial algorithm" section to set the initial output of the block, and set  discrete Modelica.Blocks.Interfaces.RealOutput RPM(fixed=true); to force the solver to use that as the initial value. You mentioned it in your post, but I wonder if the built in Modelica.Blocks.Tables.CombiTable1D component would be suitable for your model with the right parameters? You can set the smoothness to constant segments, and use the same table as you had defined previously:  Modelica.Blocks.Tables.CombiTable1D combiTable1D(table = [0, 1200; 200, 1200; 380, 1200; 450, 1400; 550, 1600; 650, 1800; 750, 1950; 850, 2100; 1000, 2100; 1200, 2100], smoothness = Modelica.Blocks.Types.Smoothness.ConstantSegments); Is that an option you think?Regards, Patrik
 Hi,thanks for the answer!It was a colleague of yours that advised against CombiTable1D if I did not want interpolation. Thinking about it, writing my own code snippet is shorter and perhaps more to the point, but using a "standard" component always has its upsides...But, if I understand you correctly, I add discrete Modelica.Blocks.Interfaces.RealOutput RPM(fixed=true); and initial algorithm RPM := 1400; Or I can go for the second option and just change:  parameter Modelica.Blocks.Types.Smoothness smoothness = Modelica.Blocks.Types.Smoothness.LinearSegments; to  parameter Modelica.Blocks.Types.Smoothness smoothness = Modelica.Blocks.Types.Smoothness.ConstantSegments; and I'd be good?Thanks, Martin