======Latence de l' OSC dans Blender====== **[[http://translate.google.com/translate?hl=&sl=auto&tl=en&u=https%3A%2F%2Fressources.labomedia.org%2Flatence_de_l_osc_dans_blender|English Version]]** ===== Définition: Wikipedia EN ===== Le [[http://en.wikipedia.org/wiki/User_Datagram_Protocol#Packet_structure|buffer UDP sur en.wikipedia]] est adressé en 16 bits. 2 puissance 16 = 65536 bits soit 8192 octets. Quelques octets sont occupés par des datas d'identification. Par exemple, une image 80 x 80 pixels avec un entier court entre 0 et 99 comme variable occupe 80 x 80 x 2 x 4 bits = 51200 bits. Le maxi serait 65000 / 2 x 4 = 8125 pixels soit 90 x 90 = 8100 pixels ! Avec 2 entiers courts possible sur chaque pixel ( ce n'est pas une image en couleurs ). ===== Description du symptôme ===== La latence peut aller jusqu'à 15 secondes ! L'action se déroule a une vitesse normale mais décalée dans le temps de 15 secondes. Après une déconnexion du serveur, Blender tourne encore pendant 15 secondes donc reçoit des datas pendant 15 secondes ! === Explication : Le tampon UDP (Buffer UDP) === Merci à [[http://blenderartists.org/forum/member.php?12684-dfelinto|**dfelinto**]] pour l'explication dans le [[http://blenderartists.org/forum/showthread.php?152785-BGE-Python-OSC-Performance-issues|post #5 sur blenderartists.org]]. Le code qu'il propose est bon à une erreur d'indentation près. Si l'envoi de data se fait à une fréquence supérieure à la lecture, le Buffer se remplit et les datas qui sont lues dans ce buffer ne sont pas les dernières envoyées. C'est un problème de **baignoire, de robinet et d'écoulement**: {{media_10:osc_05.jpg?300|fig:Osc 05.jpg}} Si le débit de sortie est plus faible que le débit d'entrèe, le niveau monte. En anglais, c'est une Queue LIFO : Last In First Out {{media_08:lifo_queue.png?300|fig:Lifo queue.png}} ===== Explications : Le Blender Game Engine pulse ===== **Pourquoi ce débit de sortie faible ?** Blender est plutôt lent, il pulse à la fréquence que vous définissez avec un maxi de 60 fps, soit **une période optimale possible de 16 ms**. Il suffit d'envoyer avec une période de 10 ms pour remplir le Buffer. Pure Data peut envoyer avec une période de 10 ms sans problème. Le test ci-dessous montre des compteurs avec des valeurs de pulse de 0, 1 et 2. Blender tourne au maximum à 60 fps: {{media_12:pulse_1.png?300|fig:Pulse 1.png}} ===== Des solutions ===== === 1 - Solution avec une initialisation de la connexion à chaque pulsation dans Blender === Si la connexion est réinitialisée à chaque pulsation de Blender, cela vide le Buffer. Mais Pure Data se déconnecte avec cette solution, cela marche avec OSCeleton et le wiiOSC de [[http://www.selectparks.net/modules.php?name=News&file=article&sid=628|Julian]]. === 2 - Solution simple : fréquence d'envoi < fréquence de réception === Le tableau ci-dessous donne les fréquences et périodes dans Blender et Pure Data. {{media_12:pulse_3.png|Pulse 3.png}} La solution la plus rationnelle est de régler la fréquence d' envoi plus basse que la fréquence de réception dans Blender, idem est régler le "timer" dans pure data à une valeur supérieure à la période dans Blender. Le tableau ci-dessus donne la période en fonction du "Pulse Mode" si Blender est à 60 "fps"! Bourrer Blender ne le fera pas aller plus vite ! Régler le "Pulse" à 0 sur tous les Actuators peut sembler efficace, mais cela va probablement faire chuter le "fps" de Blender, si le jeu est un peu lourd. === 3 - Définir la taille du Buffer UDP: la meilleure solution !=== GameLogic.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024) Ce {{media_10:osc_buffer_mini_2.49.zip| OSC buffer mini 2.49.zip}} utilise cette option, si elle est commentée le cube est en retard. === 4 - Vider le buffer si il contient plus de 1 valeur === C'est la méthode proposée par [[https://developer.blender.org/p/dfelinto/|dfelinto]]. Ce script a été testé avec un patch avec un timer de 10 ms. Sans vider le buffer, la latence est de 15 secondes, avec ce script il n' ya plus de latence. **Cette solution est lourde: Définir la taille du Buffer UDP est bien plus éléguante** import GameLogic import socket import OSC # Get controller and owner controller = GameLogic.getCurrentController() owner = controller.owner # Set init ip = 'localhost' data = 0 ######################################################################################## def receive_osc(data, port): try: # getting first data value from buffer data, port = GameLogic.socket.recvfrom(1024) # keep trying to get new data until buffer is empty try: trash = data while True: data = trash trash, port = GameLogic.socket.recvfrom(1024) # print deleted values print "trash= ", trash except: # we force this exception to happen # that way we know the buffer is empty pass except Exception as E: pass return data ######################################################################################## # Connect Blender only one time if not owner['connected']: owner['connected'] = True print "Blender Connected" GameLogic.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) GameLogic.socket.bind((ip, 4951)) GameLogic.socket.setblocking(0) GameLogic.socket.settimeout(0.02) # If Blender connected, get osc else: # Get hand wii osc from pd data = receive_osc(data, 4951) if data != 0: GameLogic.handWii = OSC.decodeOSC(data) === 5 - Définir la taille du Buffer UDP avec Pure Data === {{media_10:osc_08.png|Osc 08.png}} bufsize 1024 sur packOSC définit la taille du buffer. ===== Construire un patch pd correct ===== [[Communication_entre_Pure-data_et_Blender_en_OSC|Communication entre Pure-data et Blender en OSC]] propose des exemples pour tester et comprendre. ===== Ressources ===== * [[http://blenderartists.org/forum/showthread.php?152785-BGE-Python-OSC-Performance-issues|OSC-Performance sur blenderartists]] * [[http://ubuntuforums.org/showthread.php?t=1757909|ubuntuforums.org]] {{tag>logiciels_de_communication sb blender}}