首页 文章

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

提问于
浏览
1

假设我想模拟每天早上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;

在上面的模型中,只要 beeping 为真,我每秒产生'beep'( sample(0,1) ) . 如果我运行模拟几天,我希望每天早上01:00在我的模拟中得到10个时间事件 .

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

### STATISTICS ###
   events
      3601 time events

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

2 回答

  • 3

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

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

  • 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) .

相关问题