假设我想模拟每天早上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 回答
当您使用时间事件时,Modelica将始终以高速率进行采样,您可以使用状态事件绕过它 .
我认为还有另一种替代方案,使用Clocklica和Modelica 3.x中的新同步功能,你可以试试看 .
这取决于Modelica工具中执行的优化 . Dymola只为此生成12个时间事件(从10到0应该产生11个时间事件 - 不仅仅是10个;我没有检查第12个事件) .
正如@ sjoelund.se所示,你可以使用
time>=nextTime
,但要简单而安全而不是time>=nextTime and numTicks>0
只在有事件时设置nextTime
:我相信所有Modelica工具都能解决这个问题 .
请注意
beepsRemaining==0
与Modelica不正确,因为您要比较Reals是否相等 . 我建议使用Integer并用beepsRemaining<=0
替换测试(或上面的反转) .并且oneDay值对我来说很奇怪 . 我会用
from_hour(24)
.