2017-03-15 3 views
1

Supposons que je voudrais modéliser une horloge d'alarme qui produit 10 émet un signal sonore (un par seconde) tous les matins à 1h00:Comment placer une instruction when dans Modelica pour limiter la génération d'événements temporels?

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; 

Dans le modèle ci-dessus, je produis un « bip » toutes les secondes (sample(0,1)) tant que beeping est vrai. Je m'attendrais à avoir 10 événements de temps dans ma simulation à 01:00 chaque matin si je cours la simulation pendant plusieurs jours. Cependant, l'exécution de la simulation avec mon heure de fin réglée à 3600 secondes sous OpenModelica se traduit par un peu plus de 3600 événements de temps - un pour chaque seconde!

### STATISTICS ### 
    events 
     3601 time events 

Cela ne s'adapte pas bien si je veux simuler mon réveil sur une période de plusieurs mois. Existe-t-il un moyen de faire passer les instructions when dans Modelica afin qu'elles ne produisent que des événements temporels lorsqu'elles sont activées? Dois-je utiliser autre chose dans ce cas au lieu d'une déclaration when?

Répondre

3

Modelica échantillonnera toujours au débit élevé lorsque vous utilisez des événements temporels, vous pourrez peut-être contourner ce problème en utilisant des événements d'état.

Je pense qu'il existe une autre alternative utilisant des horloges et les nouvelles fonctionnalités synchrones dans Modelica 3.x, vous pouvez essayer et voir.

+0

Il est également possible d'utiliser le motif 'when sample (...) then nextTime: = time + 1.0; numTicks: = 10; fin quand; quand time> = nextTime et numTicks> 0 alors numTicks: = pre (numTicks) -1; nextTime: = heure + 1,0; fin quand; Il est possible qu'un outil Modelica puisse optimiser cela à un événement temporel au lieu d'un événement d'état (ou éventuellement en utilisant 'when time> = nextTime puis numTicks: = pre (numTicks) -1; nextTime: = if numTicks> 0 puis time +1.0 else pre (nextTime); fin quand; 'à la place). –

+0

@Adrian J'ai lu sur les horloges. Le seul concept que j'ai trouvé jusqu'ici est d'avoir une seule horloge et d'ajuster l'intervalle comme des «bips». – watkipet

2

Cela dépend des optimisations effectuées dans l'outil Modelica. Dymola ne génère que 12 événements de temps pour cela (passer de 10 à 0 devrait générer 11 événements de temps - pas seulement 10, je n'ai pas vérifié le 12ème).

Comme indiqué par @ sjoelund.se vous pouvez utiliser time>=nextTime, mais pour être simple et sûr au lieu de time>=nextTime and numTicks>0 seulement mis nextTime quand il y a un événement:

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

Je crois que tous les outils Modelica vont gérer cela.

Notez que beepsRemaining==0 n'est pas correct Modelica, puisque vous comparez Reals pour l'égalité. Je recommanderais d'utiliser Integer et de remplacer le test par beepsRemaining<=0 (ou l'inverse comme ci-dessus).

Et la valeur oneDay me semble étrange. J'utiliserais from_hour(24).