How do I gate a when statement in Modelica to limit time event generation?

强颜欢笑 提交于 2019-12-11 08:43:32

问题


Suppose that I'd like to model an alarm clock that produces 10 beeps (one per second) every morning at 01:00:

model DailyBeep
  import SI = Modelica.SIunits;
  import Modelica.SIunits.Conversions.*;

  constant  SI.Time oneDay    = 86459.17808  "one day in seconds";

  parameter SI.Time startTime = from_hour(1) "time to start beeping";
  parameter Real numBeeps     = 10           "the number of beeps to make";

  Boolean beeping     "true when we should beep every second";
  Real beepsRemaining "the number of beeps remaining";  
initial equation
  beeping        = false;
  beepsRemaining = numBeeps;  
algorithm
  when sample(startTime, oneDay) then
    beeping := true;
    beepsRemaining := numBeeps;
  end when "starts the beeping state";

  when beeping and sample(0, 1) then
    if beepsRemaining == 0 then
      beeping := false;
    else
      // beep() // makes a sound
      beepsRemaining := beepsRemaining - 1;
    end if;
  end when "beep every second, only when beeping is enabled";
end DailyBeep;

In the model above, I produce a 'beep' every second (sample(0,1)) so long as beeping is true. I would expect to get 10 time events in my simulation at 01:00 each morning if I run the simulation for several days.

However, running the simulation with my end time set to 3600 seconds under OpenModelica results in slightly over 3600 time events--one for every second!

### STATISTICS ###
   events
      3601 time events

This doesn't scale well if I want to simulate my alarm clock over a period of several months. Is there a way to gate when statements in Modelica such that they only produce time events when they're enabled? Should I use something else in this case instead of a when statement?


回答1:


Modelica will always sample at the high rate when you use time events, you might be able to get around it using state events.

I think there is another alternative using clocks and the new synchronous features in Modelica 3.x, you could try and see.




回答2:


This depends on the optimizations performed in the Modelica tool. Dymola only generates 12 time events for this (going from 10 to 0 should generate 11 time events - not just 10; I haven't checked for the 12th one).

As indicated by @sjoelund.se you can use time>=nextTime, but to be simple and safe instead of time>=nextTime and numTicks>0 only set nextTime when there is an event:

   when time>=nextTime then
     if beepsRemaining>0 then
        nextTime:=nextTime+1.0;
        beepsRemaining:=pre(beepsRemaining)-1;
     end if;
   end when;

I believe all Modelica tools will handle that.

Note that beepsRemaining==0 is not correct Modelica, since you are comparing Reals for equality. I would recommend using Integer and replacing the test by beepsRemaining<=0 (or the inverse as above).

And the oneDay value looks weird to me. I would use from_hour(24).



来源:https://stackoverflow.com/questions/42815089/how-do-i-gate-a-when-statement-in-modelica-to-limit-time-event-generation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!