Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

issue generating triangular wave function in Modelica

I'm trying to create a model where one Modelica variable is a triangular wave of another variable. First I tried the floor() function as below:

model test1
  final constant Real pi=2*Modelica.Math.asin(1.0);
  parameter Real b = 1;
  parameter Real a = 1;
  Real x,p,u;
equation
  if sign(sin(x*pi/b))>=0 then 
    p=a*(x-b*floor(x/b));
  else 
    p=a*(b-(x-b*floor(x/b)));
  end if;
  x=time;
  u = floor(x/b);
end test1

(x=time; is arbitrary so the model compiles)

but the result is weird, as you can see below enter image description here

zoom in:

enter image description here

somehow 0.005 seconds before the next step floor function behaves unexpectedly and becomes a linear function ending by the next value.

enter image description here

then I tried the ceil() function. everything seemed right till I realised the same problem happens with ceil() function at other values (e.g. x=13)

I would appreciate if you could:

  1. help me understand why this "glitch" happens and if it is intentional by design or a bug?
  2. how I can fix this?
  3. are there any alternatives to create a triangular wave function?

P.S. I am using this "wave function" to model the interaction between two jagged bodies"

like image 503
Foad S. Farimani Avatar asked Jan 24 '26 16:01

Foad S. Farimani


2 Answers

If you are allowed to utilize the Modelica Standard Library, you can build up a parametrized, time-based zigzag signal using the CombiTimeTable block with linear interpolation and periodic extrapolation. For example,

model Test4
  parameter Real a=2 "Amplitude";
  parameter Real b=3 "Period";
  Real y=zigzag.y[1] "Zigzag";
  Modelica.Blocks.Sources.CombiTimeTable zigzag(
    table=[0,0;b/4,a;b/4,a;b/2,0;b/2,0;3*b/4,-a;3*b/4,-a;b,0],
    extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic)
    annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
  Modelica.Blocks.Sources.Trapezoid trapezoid(
    amplitude=2*a,
    rising=b/2,
    width=0,
    falling=b/2,
    period=b,
    offset=-a)
    annotation(Placement(transformation(extent={{-80,25},{-60,45}})));
  annotation(uses(Modelica(version="3.2.2")));
end Test4;
like image 163
DelmeDelmi Avatar answered Jan 28 '26 23:01

DelmeDelmi


I don't have an explanation for the glitches in your simulation.

However, I would take another approach to the sawtooth function: I see it as an integrator integrating +1 and -1 upwards and downwards. The integration time determines the amplitude and period of the sawtooth function.

The pictures below show an implementation using MSL blocks and one using code. The simulation results below are the same for both implementations.

Best regards, Rene Just Nielsen

Block diagram: Block diagram implementation Code:

model test3
  parameter Real a=2 "amplitude";
  parameter Real b=3 "period";

  Real u, y;
initial equation 
  u = 1;
  y = 0;
equation 
  4*a/b*u = der(y);
  when y > a then
    u = -1;
  elsewhen y < -a then
    u = 1;
  end when;
end test3;

Simulation result: enter image description here

like image 31
Rene Just Nielsen Avatar answered Jan 28 '26 21:01

Rene Just Nielsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!