【问题标题】:How do I gate a when statement in Modelica to limit time event generation?如何在 Modelica 中设置 when 语句以限制时间事件的生成?
【发布时间】:2017-08-06 12:09:22
【问题描述】:

假设我想模拟一个闹钟,它每天早上 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 为真,我就会每秒发出一声“哔”声 (sample(0,1))。如果我运行模拟几天,我希望在每天早上 1:00 在我的模拟中获得 10 个时间事件。

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

### STATISTICS ###
   events
      3601 time events

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

【问题讨论】:

    标签: modelica openmodelica


    【解决方案1】:

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

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

    【讨论】:

    • 也可以使用模式when sample(...) then nextTime := time+1.0; numTicks := 10; end when; when time>=nextTime and numTicks > 0 then numTicks := pre(numTicks)-1; nextTime := time+1.0; end when;。 Modelica 工具可能会将其优化为时间事件而不是状态事件(或者可能使用 when time>=nextTime then numTicks := pre(numTicks)-1; nextTime := if numTicks>0 then time+1.0 else pre(nextTime); end when; 代替)。
    • @Adrian 我一直在阅读时钟。到目前为止,我提出的唯一概念是拥有一个时钟并随着 beeping 的变化调整间隔。
    【解决方案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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-30
      • 1970-01-01
      • 2013-05-19
      相关资源
      最近更新 更多