======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}}