3.9. Boucle de simulation#
Voir aussi
Un lien vers l’ancien cours :boucle de simulation
Objectifs
Cette ressource présente le principe de boucle de simulation et sa mise en œuvre dans le cadre du projet de ipi pour simuler des comportements dynamiques.
3.9.1. Principe#
Nous nous plaçons dans le cadre de la réalisation d’un jeu qui fonctionne plus ou moins en temps réel. La vitesse à laquelle l’état du jeu évolue est essentielle pour l’expérience du joueur. Un jeu trop rapide sera injouable alors qu’un jeu trop lent sera ennuyeux. D’autre part, il faut que le temps s’écoule de manière régulière. Il ne s’agit pas que le jeu ralentisse ou accélère en fonction de la quantité de calculs à effectuer. Il faut donc maîtriser l’écoulement du temps dans le jeu en en fonction du temps physique, celui du joueur.
Durant l’exécution du programme plusieurs activités doivent être réalisées de manière simultanée :
La simulation : L’état du jeu évolue avec le temps qui passe.
Gestion de l’affichage : L’utilisateur doit voir ce qui se passe dans le jeu.
Gestion des événements clavier : Le logiciel doit réagir aux actions du joueur.
A partir de vos connaissances en programmation procédurale, vous savez coder un programme qui réalise plusieurs choses en même temps trois choses?
Indication
Application temps réel
Lorsqu’on parle d’un jeu, d’une simulation numérique ou de réalité virtuelle, une application en temps réelle assure une correspondance entre le temps qui est simulé et le temps physique de l’utilisateur. Le temps réel s’attache également aux questions de latence. Il s’agit de maîtriser le temps qui s’écoule entre une action de l’utilisateur et sa prise en compte dans l’application.
Pour ordonnancer l’ensemble des actions à réaliser il faut un programme qui s’appuie sur une boucle de simulation. Nous concevrons le programme principal d’un jeu comme une boucle de simulation qui donnera tour à tour la main aux sections de code qui s’occupent de l’affichage, de l’interaction clavier ou de l’évolution du jeu en fonction du temps.
Indication
Boucle de simulation
Une boucle de simulation est une boucle infinie qui permet de réaliser les différentes actions nécessaires à la mise en œuvre d’un logiciel de simulation. On peut également utiliser le terme de boucle événementielle si on s’intéresse plus à l’interface homme machine (IHM). Les paramètres de la boucle de simulation peuvent être : le pas de simulation, la fréquence d’affichage et le temps de latence/réponse.
Indication
** Pas de simulation**
De la même manière que le pas de vis défini le déplacement d’une vis à chaque tour de tournevis, le pas de simulation définit l’écoulement du temps simulé à chaque tour de boucle de simulation. Dans une simulation informatique le temps d’une simulation est nécessairement discret. La pas de simulation définit cette discrétisation.
Boucle
Voici un exemple de boucle de simulation :
import time timeStep=0.1 #pas=frequence=latence=timeStep while True: t0=time.time() interact() live(timeStep) show() time.sleep(timeStep - (time.time()-t0))Voici le même exemple dans lequel la boucle de simulation est encapsulée dans une fonction
run()
:
Boucle encapsulée
import time timeStep=0.1 #pas=frequence=latence=timeStep def init(): pass #initialisation du jeu def run(): global timeStep while True: t0=time.time() interact() live(timeStep) show() time.sleep(timeStep - (time.time()-t0)) if __name__=="__main__": init() run()La fonction
interact()
gère la récupération des événements du clavier et la fonctionshow()
actualise l’affichage du jeu. Ces fonctions seront décrites dans la partie de cours : interface. La fonctionlive()
fait « vivre » les éléments du jeu pendant un petit intervalle de temps.
- Ainsi une boucle de simulation permet de gérer les propriétés suivantes:
le pas de simulation qui permet de régler la précision des calculs réalisés dans le jeu.
la fréquence d’affichage qui doit être inférieure à celle de l’écran (souvent 60Hz) et assez élevé pour le confort de l’utilisateur.
le temps de réponse/latence qui représente le temps maximum entre le moment ou un joueur appuie sur une touche et le moment ou cela se traduit par un effet dans le jeu.
C’est trois propriétés peuvent être identiques ou différentes selon la complexité de la boucle de simulation. Le réglage de ces propriétés permettent le compromis entre capacité de calcul et ergonomie du jeu. Les exercices suivants permettent de produire des boucles de simulations jouant sur ces propriétés.
3.9.2. Exercices#
3.10. Résolution d’équations différentielles#
Il est possible d’utiliser une boucle de simulation pour simuler le déplacement d’un objet au cours du temps. L’idée est de réaliser un petit déplacement de l’objet en question à chaque tour de boucle. Si le pas de temps est suffisamment petit, l’utilisateur aura l’illusion d’observer un objet se déplaçant de manière continue.
Pour rendre le déplacement de l’objet réaliste on peut assez facilement lui appliquer des lois physiques ou mécaniques. Par exemple, on peut doter l’objet d’une vitesse et appliquer cette vitesse à chaque petit déplacement en fonction du pas de temps choisi.
En faisant cela, à chaque passage dans la boucle de simulation on réalise en fait un calcul d’intégration d’équations différentielles sur un pas de temps, en utilisant une méthode de résolution. Cette méthode de résolution se nomme méthode d’Euler explicite.
- Soient x et y les coordonnées d’un solide en mouvement:
\(\left\{ \begin{array}{l} \displaystyle\frac {dx}{dt} = v_x\\[8pt] \displaystyle\frac {dy}{dt} = v_y\\ \end{array} \right.\)
- On peut calculer la postion à l’instant t en fonction de la position précédente:
\(x_t=x_{t-1} + v_x * dt\)
\(y_t=y_{t-1} + v_y * dt\)
Il est très facile de traduire ces équations en algorithme:
while True:
position[0]=position[0] + (dt * vitesse[0])
position[1]=position[1] + (dt * vitesse[1])
Ici, votre formation d’ingénieur généraliste va pouvoir vous servir. Vous pouvez traduire les différentes lois dynamiques abordées en mécanique ou en électronique en algorithme décrivant le comportement d’objets de votre jeu. Par exemple, la charge d’un condensateur ou le déplacement d’un mobile s’exprime avec des équations différentielles. Cela vous permet d’être créatif tout en proposant rapidement des comportements réalistes. Par ailleurs vous n’avez pas à vous soucier de résoudre le système d’équations différentielles, vous devez simplement le simuler. Vous devez par contre vous assurer que le pas de temps choisi pour les calculs est assez petit pour garantir une précision des calculs adaptée au contexte. Bien sûr, lorsque les lois se compliquent il faut faire appelle à des outils de résolution plus efficaces. Le cours de méthodes numériques de S5 vous présentera quelques éléments à ce sujet. En attendant, la méthode d’Euler qui vous est donnée ici permet déjà beaucoup de choses.
Indication
Quand utiliser une résolution d’équations différentielles?
« …la balle se déplace à une certaine vitesse… »
« …les boulets de canon ont une vitesse initiale et sont soumis à la gravitée… »
Alcootest
############################# ## euler.py ## ## exemple de cours ipi ## ## Gireg Demseulles ## ## 19/02/2014 ## ############################################################ ## illustation boucle de simulation : methode d euler ## ############################################################ import time def init(): parameters = dict() parameters['dt'] = 1 #seconde parameters['logStep'] = 600 #doit etre > dt #poids du sujet p=float(input("quel poids?")) #volume de sang s=float(p/100.0*7.5) #quantite d alcool q=input("combien d unites d alcool ont etes consommees") parameters['alcool'] = float(q)/s #g / L parameters['limite'] = 0.5 #g / L parameters['vitesse'] = 0.00002778 #g / L.s return parameters def run(parameters): #boucle de simulation logTimer = parameters['logStep'] t=0.0 #boucle de simulation log(parameters,t) while(parameters['alcool'] > parameters['limite']): #integre step(parameters) t=t+parameters['dt'] #log logTimer = logTimer - parameters['dt'] if logTimer < 0: log(parameters,t) logTimer=parameters['logStep'] msg = "Vous devez attendre " + str(t/60.0) + " minutes avant de prendre le volant" print(msg) def step(parameters): #integre sur un pas de temps parameters['alcool']=parameters['alcool'] - (parameters['vitesse']*parameters['dt']) def log(parameters,t): msg ="t=" + str(t) + " alcool=" + str(parameters['alcool']) print(msg) if __name__ == '__main__': parameters = init() run(parameters)
3.10.1. Exercices#
3.11. Machine à états#
Indication
Machine à états finis
Une machine à états finis peut être vue comme un graphe auquel on associe les sommets à des états et les liens à des transitions. De plus, la machine à états possède un état courant.
Nous savons mettre en œuvre une boucle de simulation et déplacer les objets de notre jeu selon une des lois physiques ou plus ou moins réalistes. Maintenant, comment pourrions nous associer plusieurs loi de déplacement à un même objet et sélectionner une en particulier selon le contexte du jeu? Par Exemple, un ennemi dans l’état « normal » possède une vitesse de déplacement constante et dans l’état « en colère », se déplace de manière aléatoire. Il faut pour cela conserver en mémoire une information concernant l”état de la donnée pour laquelle on souhaite définir le comportement.
Le fait de conserver en mémoire l’état d’un élément d’un tour à l’autre de la boucle de simulation, le fait d’associer des actions différentes à chaque état et des conditions faisant évoluer l’état
Le Grafcet est aussi une machine à état.
Indication
Quand utiliser une machine à état?
« …Les monstres se déplacent aléatoirement. Dès qu’ils repèrent le joueur, ils se dirigent dans sa direction… »
« …Le jeux reprend le principe des livres dont vous êtes le héros… »
Prudence
vous pouvez étudier les codes suivants.
machine à états minimaliste
state="a" t=0 #boucle de simulation while state!="exit": if (state=="a"): if t > 10 : state ="b" elif (state=="b"): state ="c" elif (state=="c"): if t > 100 : state ="exit" print state t=t+1 print ("fin de boucle")
machine a état plus élaborée
exemple_animat.zip