Message Boards Message Boards

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

Posted 7 years ago

Hi,

Edited: formatted code snippet

I 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

POSTED BY: Martin Nilsson
3 Replies
Posted 7 years ago

Update:

The first option did not work. The model always output the inital value set. I have upstream and downstream fixed variables so that might be some internal power struggles between various models so that no event actually occurs.

The second option, however, worked like a charm :-)

Since the previous version of my code was interpolation using CombiTables just changes those six letters was indeed very easy.

POSTED BY: Martin Nilsson
Posted 7 years ago

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

POSTED BY: Martin Nilsson

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

POSTED BY: Patrik Ekenberg
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract