如何在Modelica中关闭when语句以限制时间事件生成?

时间:2017-03-15 16:09:31

标签: modelica openmodelica

假设我想建立一个每天早上01:00产生10次哔哔声(每秒一次)的闹钟:

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;

在上面的模型中,我发出了一声“哔哔”声。每隔一秒(sample(0,1)),只要beeping为真。如果我运行模拟几天,我希望每天早上01:00在我的模拟中得到10个时间事件。

但是,在OpenModelica下将我的结束时间设置为3600秒运行模拟会导致稍微超过3600个时间事件 - 每秒一个!

### STATISTICS ###
   events
      3601 time events

如果我想在几个月的时间内模拟我的闹钟,这并不能很好地扩展。有没有办法在Modelica中对when语句进行处理,以便它们只在启用时生成时间事件?在这种情况下我应该使用其他东西而不是when语句吗?

2 个答案:

答案 0 :(得分:3)

当您使用时间事件时,Modelica将始终以高速率进行采样,您可以使用状态事件绕过它。

我认为在Modelica 3.x中还有另一种使用时钟和新同步功能的替代方案,你可以试试看。

答案 1 :(得分:2)

这取决于Modelica工具中执行的优化。 Dymola只为此生成12个时间事件(从10到0应该产生11个时间事件 - 不仅仅是10个;我还没有检查过第12个事件)。

正如@ sjoelund.se所示,您可以使用time>=nextTime,但要简单而安全而不是time>=nextTime and numTicks>0,只有在发生事件时设置nextTime

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

我相信所有Modelica工具都会处理它。

请注意,beepsRemaining==0与Modelica不正确,因为您要比较Reals的相等性。我建议使用Integer并用beepsRemaining<=0替换测试(或上面的反转)。

oneDay值对我来说很奇怪。我会使用from_hour(24)