Je travaille actuellement sur le développement d'un script python permettant
d'utiliser le gant P5 glove sous blender.
Le système est divisé en deux partie une application Java récupère les
données du gant et reconnaît les geste effectué par l'utilisateur.
L'appli Java intègre un client qui envoie par mécanisme de socket les
résultat du traitement à l'appli Python.
Au sein de mon appli python j'ai crée un thread qui écoute et réceptionne en
permanence les paquets venant du client.
L'appli python est composée de d'une petit interface graphique spécifique à
Blender et d'une fonction qui déplace un objet en fonction des coordonnées
du gant. Au sein du thread "réception" il y une boucle infinie, mais ce que
je ne comprend pas c'est qu'il y a execution d'un tour de boucle uniquement
si l'interface capte un événement (mouvement de souris, ou pression d'une
touche). Ainsi quand je bouge la souris d'un pixel la boucle fait un tour
....
Je ne comprend pas trop, le thread n'est-il pas sensé être indépendant ?
Comment pourrait on forcer son exécution alors que je n'ai pas de boucle
dans mon code principal (il existe une boucle qui attend les événements mais
je n'ai pas d'accès a son code et donc ne peux pas mettre de pause).
quelqu'un a t'il déjà eu ce type de problème ?
Merci d'avance
le source de application python est disponible à l'adresse suivante:
glClearColor(0.9,0.9,0.9,1) glClear(GL_COLOR_BUFFER_BIT) glColor3f(0,0,0) # defnie la couleur de la fenetre glRasterPos2d(8, 320) # defnie une postion Text("P5 Glove / Blender") # texte commentaire glRasterPos2d(8, 300) # definie une position Text("ESC pour quitter") # texte commentaire
Button("Activer",EVENT_ACTIVER,100,10,80,19) # Bouton pour activer le pilotage Button("Désactiver",EVENT_DESACTIVER,190,10,80,19) # Bouton pour déactiver le pilotage Button("Exit",EVENT_EXIT,280,10,80,19) # Bouton de sortie
def event(evt, val): # gestion des evenements if (evt==ESCKEY): # Press la touche echap Exit() # quitte l'execution du script Redraw(1) return
def BtnEvent (evt): # gestion des Evenements bouton if(evt==EVENT_ACTIVER): th=thread.start_new_thread(reception,()) # lancement du thread de reception des paquets if(evt==EVENT_DESACTIVER): th.exit() #deactiver le thread if (evt==EVENT_EXIT): Exit() Redraw(1) return
def ClientStop(): # lorsque que le client s'arrete print "Le client a quitte" UDPSock.close()
def MoveCub(x,y,z): # fonction deplace un cube selon les coordonnées du gant dans l'espace print "nx:",x,"y:",y,"z:",z # affiche les coordonnées du gant obj=Blender.Object.Get('Cube') obj.setEuler(0,0,0) obj.setLocation(x,y,z) #deplace le cube selon les coordonnées du gant obj.select(1) #print str(obj) #sys.stdout.flush()
def reception(): # fonction thread qui reception les paquets du client host = "localhost" # Adresse du serveur port = 12345 # Port du serveur buf = 1024 # Taille du Buffer addr = (host,port) UDPSock = socket(AF_INET,SOCK_DGRAM) #creation du socket (type UDP) UDPSock.bind(addr) # On bind l'adresse print "in thread" while 1: x="" # coordonnée du gant dans l'espace y="" z="" data,addr = UDPSock.recvfrom(buf) # recuperation des paquets i=0 # ci dessous bout de code permettant de decoupé les paquets pour recuperer les coordonnés et les stocker dans les variables x,y,z while(data[i+1]!="y"): x=x+data[i+1] i=i+1 i=i+1 while(data[i+1]!="z"): y=y+data[i+1] i=i+1 i=i+1 while(data[i+1]!="/"): z=z+data[i+1] i=i+1 # Fin du decoupage des données MoveCub(float(x),float(y),float(z)) #appel de la fonction qui deplace le cube
print "Interface execute, cliquer sur Activer pour lancer le thread Server" Register(gui,event,BtnEvent) # lancement de l'interface graphique
# Application de gestion du gant P5Glove sous blender
# Antoine ANDRE, Jacques DAUSSY
# Lib Python 2.3 minimun pour utiliser Socket et thread
# Importe socket..
import Blender
import time
import thread
from Blender import NMesh
from Blender import Object
from Blender.BGL import *
from Blender.Draw import *
from socket import *
import sys
glClearColor(0.9,0.9,0.9,1)
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0,0,0) # defnie la couleur de la fenetre
glRasterPos2d(8, 320) # defnie une postion
Text("P5 Glove / Blender") # texte commentaire
glRasterPos2d(8, 300) # definie une position
Text("ESC pour quitter") # texte commentaire
Button("Activer",EVENT_ACTIVER,100,10,80,19) # Bouton pour
activer le pilotage
Button("Désactiver",EVENT_DESACTIVER,190,10,80,19) # Bouton pour
déactiver le pilotage
Button("Exit",EVENT_EXIT,280,10,80,19) # Bouton de sortie
def event(evt, val): # gestion des evenements
if (evt==ESCKEY): # Press la touche echap
Exit() # quitte l'execution du script
Redraw(1)
return
def BtnEvent (evt): # gestion des Evenements bouton
if(evt==EVENT_ACTIVER):
th=thread.start_new_thread(reception,()) # lancement du thread de
reception des paquets
if(evt==EVENT_DESACTIVER):
th.exit() #deactiver le thread
if (evt==EVENT_EXIT):
Exit()
Redraw(1)
return
def ClientStop(): # lorsque que le client s'arrete
print "Le client a quitte"
UDPSock.close()
def MoveCub(x,y,z): # fonction deplace un cube selon les coordonnées du gant
dans l'espace
print "nx:",x,"y:",y,"z:",z # affiche les coordonnées du gant
obj=Blender.Object.Get('Cube')
obj.setEuler(0,0,0)
obj.setLocation(x,y,z) #deplace le cube selon les coordonnées du gant
obj.select(1)
#print str(obj)
#sys.stdout.flush()
def reception(): # fonction thread qui reception les paquets du
client
host = "localhost" # Adresse du serveur
port = 12345 # Port du serveur
buf = 1024 # Taille du Buffer
addr = (host,port)
UDPSock = socket(AF_INET,SOCK_DGRAM) #creation du socket (type UDP)
UDPSock.bind(addr) # On bind l'adresse
print "in thread"
while 1:
x="" # coordonnée du gant dans l'espace
y=""
z=""
data,addr = UDPSock.recvfrom(buf) # recuperation des paquets
i=0 # ci dessous bout de code permettant de
decoupé les paquets pour recuperer les coordonnés et les stocker dans les
variables x,y,z
while(data[i+1]!="y"):
x=x+data[i+1]
i=i+1
i=i+1
while(data[i+1]!="z"):
y=y+data[i+1]
i=i+1
i=i+1
while(data[i+1]!="/"):
z=z+data[i+1]
i=i+1 # Fin du decoupage des données
MoveCub(float(x),float(y),float(z)) #appel de la fonction qui
deplace le cube
print "Interface execute, cliquer sur Activer pour lancer le thread Server"
Register(gui,event,BtnEvent) # lancement de l'interface graphique
glClearColor(0.9,0.9,0.9,1) glClear(GL_COLOR_BUFFER_BIT) glColor3f(0,0,0) # defnie la couleur de la fenetre glRasterPos2d(8, 320) # defnie une postion Text("P5 Glove / Blender") # texte commentaire glRasterPos2d(8, 300) # definie une position Text("ESC pour quitter") # texte commentaire
Button("Activer",EVENT_ACTIVER,100,10,80,19) # Bouton pour activer le pilotage Button("Désactiver",EVENT_DESACTIVER,190,10,80,19) # Bouton pour déactiver le pilotage Button("Exit",EVENT_EXIT,280,10,80,19) # Bouton de sortie
def event(evt, val): # gestion des evenements if (evt==ESCKEY): # Press la touche echap Exit() # quitte l'execution du script Redraw(1) return
def BtnEvent (evt): # gestion des Evenements bouton if(evt==EVENT_ACTIVER): th=thread.start_new_thread(reception,()) # lancement du thread de reception des paquets if(evt==EVENT_DESACTIVER): th.exit() #deactiver le thread if (evt==EVENT_EXIT): Exit() Redraw(1) return
def ClientStop(): # lorsque que le client s'arrete print "Le client a quitte" UDPSock.close()
def MoveCub(x,y,z): # fonction deplace un cube selon les coordonnées du gant dans l'espace print "nx:",x,"y:",y,"z:",z # affiche les coordonnées du gant obj=Blender.Object.Get('Cube') obj.setEuler(0,0,0) obj.setLocation(x,y,z) #deplace le cube selon les coordonnées du gant obj.select(1) #print str(obj) #sys.stdout.flush()
def reception(): # fonction thread qui reception les paquets du client host = "localhost" # Adresse du serveur port = 12345 # Port du serveur buf = 1024 # Taille du Buffer addr = (host,port) UDPSock = socket(AF_INET,SOCK_DGRAM) #creation du socket (type UDP) UDPSock.bind(addr) # On bind l'adresse print "in thread" while 1: x="" # coordonnée du gant dans l'espace y="" z="" data,addr = UDPSock.recvfrom(buf) # recuperation des paquets i=0 # ci dessous bout de code permettant de decoupé les paquets pour recuperer les coordonnés et les stocker dans les variables x,y,z while(data[i+1]!="y"): x=x+data[i+1] i=i+1 i=i+1 while(data[i+1]!="z"): y=y+data[i+1] i=i+1 i=i+1 while(data[i+1]!="/"): z=z+data[i+1] i=i+1 # Fin du decoupage des données MoveCub(float(x),float(y),float(z)) #appel de la fonction qui deplace le cube
print "Interface execute, cliquer sur Activer pour lancer le thread Server" Register(gui,event,BtnEvent) # lancement de l'interface graphique
Amaury Forgeot d'Arc
Bonjour, ...
Au sein de mon appli python j'ai crée un thread qui écoute et réceptionne en permanence les paquets venant du client.
L'appli python est composée de d'une petit interface graphique spécifique à Blender et d'une fonction qui déplace un objet en fonction des coordonnées du gant. Au sein du thread "réception" il y une boucle infinie, mais ce que je ne comprend pas c'est qu'il y a execution d'un tour de boucle uniquement si l'interface capte un événement (mouvement de souris, ou pression d'une touche). Ainsi quand je bouge la souris d'un pixel la boucle fait un tour ....
Je ne comprend pas trop, le thread n'est-il pas sensé être indépendant ? Comment pourrait on forcer son exécution alors que je n'ai pas de boucle dans mon code principal (il existe une boucle qui attend les événements mais je n'ai pas d'accès a son code et donc ne peux pas mettre de pause).
quelqu'un a t'il déjà eu ce type de problème ?
Merci d'avance
Je ne connais pas Blender, mais ce genre de comportement me rappelle des soucis avec le GIL de python. Je m'explique :
L'exécution de Python n'est pas réellement multi-threads. Quand plusieurs threads veulent exécuter du python, ils se partagent le GIL (Global Interpreter Lock). Seul le thread qui possède le GIL peut avancer dans l'exécution de son code python.
Le GIL peut passer d'un thread à l'autre par deux mécanismes : d'abord, l'interpréteur force ce passage toutes les 100 instructions (je crois, vérifie sys.getcheckinterval()) ; ensuite, quand une fonction le relâche explicitement avant de faire une opération longue en C. Par exemple, la fonction socket.receive() relâche le GIL pendant qu'elle attend des données, puis le redemande avant de retourner son résultat au code appelant.
Ton problème peut s'interpréter comme ceci : comme la fonction Register ne relâche pas le GIL, le thread "réception" ne tourne pas. Quand l'interface capte un événement, elle appelle les fonctions "event" et "BntEvent" ce qui au bout de 100 instructions passe la main au thread "réception". Et bien sûr, le thread "réception" relâche le GIL quand il tente de lire un paquet.
Si mon interprétation est bonne, je ne vois malheureusement pas de solution autre que de réécrire Blender pour le forcer à relâcher ce fameux GIL...
Amaury.
Bonjour,
...
Au sein de mon appli python j'ai crée un thread qui écoute et réceptionne en
permanence les paquets venant du client.
L'appli python est composée de d'une petit interface graphique spécifique à
Blender et d'une fonction qui déplace un objet en fonction des coordonnées
du gant. Au sein du thread "réception" il y une boucle infinie, mais ce que
je ne comprend pas c'est qu'il y a execution d'un tour de boucle uniquement
si l'interface capte un événement (mouvement de souris, ou pression d'une
touche). Ainsi quand je bouge la souris d'un pixel la boucle fait un tour
....
Je ne comprend pas trop, le thread n'est-il pas sensé être indépendant ?
Comment pourrait on forcer son exécution alors que je n'ai pas de boucle
dans mon code principal (il existe une boucle qui attend les événements mais
je n'ai pas d'accès a son code et donc ne peux pas mettre de pause).
quelqu'un a t'il déjà eu ce type de problème ?
Merci d'avance
Je ne connais pas Blender, mais ce genre de comportement me rappelle des
soucis avec le GIL de python. Je m'explique :
L'exécution de Python n'est pas réellement multi-threads. Quand
plusieurs threads veulent exécuter du python, ils se partagent le GIL
(Global Interpreter Lock). Seul le thread qui possède le GIL peut
avancer dans l'exécution de son code python.
Le GIL peut passer d'un thread à l'autre par deux mécanismes : d'abord,
l'interpréteur force ce passage toutes les 100 instructions (je crois,
vérifie sys.getcheckinterval()) ; ensuite, quand une fonction le relâche
explicitement avant de faire une opération longue en C.
Par exemple, la fonction socket.receive() relâche le GIL pendant qu'elle
attend des données, puis le redemande avant de retourner son résultat au
code appelant.
Ton problème peut s'interpréter comme ceci : comme la fonction Register
ne relâche pas le GIL, le thread "réception" ne tourne pas.
Quand l'interface capte un événement, elle appelle les fonctions "event"
et "BntEvent" ce qui au bout de 100 instructions passe la main au thread
"réception". Et bien sûr, le thread "réception" relâche le GIL quand il
tente de lire un paquet.
Si mon interprétation est bonne, je ne vois malheureusement pas de
solution autre que de réécrire Blender pour le forcer à relâcher ce
fameux GIL...
Au sein de mon appli python j'ai crée un thread qui écoute et réceptionne en permanence les paquets venant du client.
L'appli python est composée de d'une petit interface graphique spécifique à Blender et d'une fonction qui déplace un objet en fonction des coordonnées du gant. Au sein du thread "réception" il y une boucle infinie, mais ce que je ne comprend pas c'est qu'il y a execution d'un tour de boucle uniquement si l'interface capte un événement (mouvement de souris, ou pression d'une touche). Ainsi quand je bouge la souris d'un pixel la boucle fait un tour ....
Je ne comprend pas trop, le thread n'est-il pas sensé être indépendant ? Comment pourrait on forcer son exécution alors que je n'ai pas de boucle dans mon code principal (il existe une boucle qui attend les événements mais je n'ai pas d'accès a son code et donc ne peux pas mettre de pause).
quelqu'un a t'il déjà eu ce type de problème ?
Merci d'avance
Je ne connais pas Blender, mais ce genre de comportement me rappelle des soucis avec le GIL de python. Je m'explique :
L'exécution de Python n'est pas réellement multi-threads. Quand plusieurs threads veulent exécuter du python, ils se partagent le GIL (Global Interpreter Lock). Seul le thread qui possède le GIL peut avancer dans l'exécution de son code python.
Le GIL peut passer d'un thread à l'autre par deux mécanismes : d'abord, l'interpréteur force ce passage toutes les 100 instructions (je crois, vérifie sys.getcheckinterval()) ; ensuite, quand une fonction le relâche explicitement avant de faire une opération longue en C. Par exemple, la fonction socket.receive() relâche le GIL pendant qu'elle attend des données, puis le redemande avant de retourner son résultat au code appelant.
Ton problème peut s'interpréter comme ceci : comme la fonction Register ne relâche pas le GIL, le thread "réception" ne tourne pas. Quand l'interface capte un événement, elle appelle les fonctions "event" et "BntEvent" ce qui au bout de 100 instructions passe la main au thread "réception". Et bien sûr, le thread "réception" relâche le GIL quand il tente de lire un paquet.
Si mon interprétation est bonne, je ne vois malheureusement pas de solution autre que de réécrire Blender pour le forcer à relâcher ce fameux GIL...
Amaury.
F. Petitjean
# Application de gestion du gant P5Glove sous blender # Antoine ANDRE, Jacques DAUSSY # Lib Python 2.3 minimun pour utiliser Socket et thread
# Importe socket.. import Blender import time import thread from Blender import NMesh from Blender import Object from Blender.BGL import * from Blender.Draw import * from socket import * S'il vous plaît n'utilisez pas from module import *
glClearColor(0.9,0.9,0.9,1) glClear(GL_COLOR_BUFFER_BIT) glColor3f(0,0,0) # defnie la couleur de la fenetre glRasterPos2d(8, 320) # defnie une postion Text("P5 Glove / Blender") # texte commentaire glRasterPos2d(8, 300) # definie une position Text("ESC pour quitter") # texte commentaire
Button("Activer",EVENT_ACTIVER,100,10,80,19) # Bouton pour activer le pilotage Button("Désactiver",EVENT_DESACTIVER,190,10,80,19) # Bouton pour déactiver le pilotage Button("Exit",EVENT_EXIT,280,10,80,19) # Bouton de sortie
def event(evt, val): # gestion des evenements if (evt==ESCKEY): # Press la touche echap Exit() # quitte l'execution du script Redraw(1) return
def BtnEvent (evt): # gestion des Evenements bouton if(evt==EVENT_ACTIVER): th=thread.start_new_thread(reception,()) # lancement du thread de reception des paquets if(evt==EVENT_DESACTIVER): th.exit() #deactiver le thread if (evt==EVENT_EXIT): Exit() Redraw(1) return Il me semble que utiliser le module thread au lieu de threading
n'est pas une super idée pour un débutant : imaginer ce que devient la variable essentielle th qui identifie le thread lorsque la fonction se termine ? Comme toute variable locale elle est envoyée par gc (garbage collector) dans le cyber-espace. Je vous conseille de reprendre le script avec une classe dérivée de threading.Thread et éventiellement une classe qui permette de lier le tout (th sera alors un attrinut de cette classe Gant et donc ne sera pas « garbage collected » tant qu'il y aura une référence gant.th sur cet objet).
def ClientStop(): # lorsque que le client s'arrete print "Le client a quitte" UDPSock.close() UDPSock vient d'où ?
def MoveCub(x,y,z): # fonction deplace un cube selon les coordonnées du gant dans l'espace print "nx:",x,"y:",y,"z:",z # affiche les coordonnées du gant obj=Blender.Object.Get('Cube') obj.setEuler(0,0,0) obj.setLocation(x,y,z) #deplace le cube selon les coordonnées du gant obj.select(1) #print str(obj) #sys.stdout.flush()
def reception(): # fonction thread qui reception les paquets du client host = "localhost" # Adresse du serveur port = 12345 # Port du serveur buf = 1024 # Taille du Buffer addr = (host,port) UDPSock = socket(AF_INET,SOCK_DGRAM) #creation du socket (type UDP) UDPSock.bind(addr) # On bind l'adresse print "in thread" while 1: x="" # coordonnée du gant dans l'espace y="" z="" data,addr = UDPSock.recvfrom(buf) # recuperation des paquets i=0 # ci dessous bout de code permettant de decoupé les paquets pour recuperer les coordonnés et les stocker dans les variables x,y,z while(data[i+1]!="y"): x=x+data[i+1] i=i+1 i=i+1 while(data[i+1]!="z"): y=y+data[i+1] i=i+1 i=i+1 while(data[i+1]!="/"): z=z+data[i+1] i=i+1 # Fin du decoupage des données MoveCub(float(x),float(y),float(z)) #appel de la fonction qui deplace le cube
print "Interface execute, cliquer sur Activer pour lancer le thread Server" Register(gui,event,BtnEvent) # lancement de l'interface graphique Ce Register vient d'où ? (vous auriez pu ajouter une petite explication)
# Application de gestion du gant P5Glove sous blender
# Antoine ANDRE, Jacques DAUSSY
# Lib Python 2.3 minimun pour utiliser Socket et thread
# Importe socket..
import Blender
import time
import thread
from Blender import NMesh
from Blender import Object
from Blender.BGL import *
from Blender.Draw import *
from socket import *
S'il vous plaît n'utilisez pas from module import *
glClearColor(0.9,0.9,0.9,1)
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0,0,0) # defnie la couleur de la fenetre
glRasterPos2d(8, 320) # defnie une postion
Text("P5 Glove / Blender") # texte commentaire
glRasterPos2d(8, 300) # definie une position
Text("ESC pour quitter") # texte commentaire
Button("Activer",EVENT_ACTIVER,100,10,80,19) # Bouton pour
activer le pilotage
Button("Désactiver",EVENT_DESACTIVER,190,10,80,19) # Bouton pour
déactiver le pilotage
Button("Exit",EVENT_EXIT,280,10,80,19) # Bouton de sortie
def event(evt, val): # gestion des evenements
if (evt==ESCKEY): # Press la touche echap
Exit() # quitte l'execution du script
Redraw(1)
return
def BtnEvent (evt): # gestion des Evenements bouton
if(evt==EVENT_ACTIVER):
th=thread.start_new_thread(reception,()) # lancement du thread de
reception des paquets
if(evt==EVENT_DESACTIVER):
th.exit() #deactiver le thread
if (evt==EVENT_EXIT):
Exit()
Redraw(1)
return
Il me semble que utiliser le module thread au lieu de threading
n'est pas une super idée pour un débutant : imaginer ce que devient la
variable essentielle th qui identifie le thread lorsque la fonction se
termine ? Comme toute variable locale elle est envoyée par gc (garbage
collector) dans le cyber-espace.
Je vous conseille de reprendre le script avec une classe dérivée de
threading.Thread et éventiellement une classe qui permette de lier le
tout (th sera alors un attrinut de cette classe Gant et donc ne sera
pas « garbage collected » tant qu'il y aura une référence gant.th sur
cet objet).
def ClientStop(): # lorsque que le client s'arrete
print "Le client a quitte"
UDPSock.close()
UDPSock vient d'où ?
def MoveCub(x,y,z): # fonction deplace un cube selon les coordonnées du gant
dans l'espace
print "nx:",x,"y:",y,"z:",z # affiche les coordonnées du gant
obj=Blender.Object.Get('Cube')
obj.setEuler(0,0,0)
obj.setLocation(x,y,z) #deplace le cube selon les coordonnées du gant
obj.select(1)
#print str(obj)
#sys.stdout.flush()
def reception(): # fonction thread qui reception les paquets du
client
host = "localhost" # Adresse du serveur
port = 12345 # Port du serveur
buf = 1024 # Taille du Buffer
addr = (host,port)
UDPSock = socket(AF_INET,SOCK_DGRAM) #creation du socket (type UDP)
UDPSock.bind(addr) # On bind l'adresse
print "in thread"
while 1:
x="" # coordonnée du gant dans l'espace
y=""
z=""
data,addr = UDPSock.recvfrom(buf) # recuperation des paquets
i=0 # ci dessous bout de code permettant de
decoupé les paquets pour recuperer les coordonnés et les stocker dans les
variables x,y,z
while(data[i+1]!="y"):
x=x+data[i+1]
i=i+1
i=i+1
while(data[i+1]!="z"):
y=y+data[i+1]
i=i+1
i=i+1
while(data[i+1]!="/"):
z=z+data[i+1]
i=i+1 # Fin du decoupage des données
MoveCub(float(x),float(y),float(z)) #appel de la fonction qui
deplace le cube
print "Interface execute, cliquer sur Activer pour lancer le thread Server"
Register(gui,event,BtnEvent) # lancement de l'interface graphique
Ce Register vient d'où ? (vous auriez pu ajouter une petite explication)
# Application de gestion du gant P5Glove sous blender # Antoine ANDRE, Jacques DAUSSY # Lib Python 2.3 minimun pour utiliser Socket et thread
# Importe socket.. import Blender import time import thread from Blender import NMesh from Blender import Object from Blender.BGL import * from Blender.Draw import * from socket import * S'il vous plaît n'utilisez pas from module import *
glClearColor(0.9,0.9,0.9,1) glClear(GL_COLOR_BUFFER_BIT) glColor3f(0,0,0) # defnie la couleur de la fenetre glRasterPos2d(8, 320) # defnie une postion Text("P5 Glove / Blender") # texte commentaire glRasterPos2d(8, 300) # definie une position Text("ESC pour quitter") # texte commentaire
Button("Activer",EVENT_ACTIVER,100,10,80,19) # Bouton pour activer le pilotage Button("Désactiver",EVENT_DESACTIVER,190,10,80,19) # Bouton pour déactiver le pilotage Button("Exit",EVENT_EXIT,280,10,80,19) # Bouton de sortie
def event(evt, val): # gestion des evenements if (evt==ESCKEY): # Press la touche echap Exit() # quitte l'execution du script Redraw(1) return
def BtnEvent (evt): # gestion des Evenements bouton if(evt==EVENT_ACTIVER): th=thread.start_new_thread(reception,()) # lancement du thread de reception des paquets if(evt==EVENT_DESACTIVER): th.exit() #deactiver le thread if (evt==EVENT_EXIT): Exit() Redraw(1) return Il me semble que utiliser le module thread au lieu de threading
n'est pas une super idée pour un débutant : imaginer ce que devient la variable essentielle th qui identifie le thread lorsque la fonction se termine ? Comme toute variable locale elle est envoyée par gc (garbage collector) dans le cyber-espace. Je vous conseille de reprendre le script avec une classe dérivée de threading.Thread et éventiellement une classe qui permette de lier le tout (th sera alors un attrinut de cette classe Gant et donc ne sera pas « garbage collected » tant qu'il y aura une référence gant.th sur cet objet).
def ClientStop(): # lorsque que le client s'arrete print "Le client a quitte" UDPSock.close() UDPSock vient d'où ?
def MoveCub(x,y,z): # fonction deplace un cube selon les coordonnées du gant dans l'espace print "nx:",x,"y:",y,"z:",z # affiche les coordonnées du gant obj=Blender.Object.Get('Cube') obj.setEuler(0,0,0) obj.setLocation(x,y,z) #deplace le cube selon les coordonnées du gant obj.select(1) #print str(obj) #sys.stdout.flush()
def reception(): # fonction thread qui reception les paquets du client host = "localhost" # Adresse du serveur port = 12345 # Port du serveur buf = 1024 # Taille du Buffer addr = (host,port) UDPSock = socket(AF_INET,SOCK_DGRAM) #creation du socket (type UDP) UDPSock.bind(addr) # On bind l'adresse print "in thread" while 1: x="" # coordonnée du gant dans l'espace y="" z="" data,addr = UDPSock.recvfrom(buf) # recuperation des paquets i=0 # ci dessous bout de code permettant de decoupé les paquets pour recuperer les coordonnés et les stocker dans les variables x,y,z while(data[i+1]!="y"): x=x+data[i+1] i=i+1 i=i+1 while(data[i+1]!="z"): y=y+data[i+1] i=i+1 i=i+1 while(data[i+1]!="/"): z=z+data[i+1] i=i+1 # Fin du decoupage des données MoveCub(float(x),float(y),float(z)) #appel de la fonction qui deplace le cube
print "Interface execute, cliquer sur Activer pour lancer le thread Server" Register(gui,event,BtnEvent) # lancement de l'interface graphique Ce Register vient d'où ? (vous auriez pu ajouter une petite explication)
Franck
Comment pourrait on forcer son exécution alors que je n'ai pas de boucle dans mon code principal (il existe une boucle qui attend les événements mais je n'ai pas d'accès a son code et donc ne peux pas mettre de pause).
quelqu'un a t'il déjà eu ce type de problème ?
J'ai eu ce problème avec PyGTK dont la boucle d'événement semble garder la main (ou le GIL comme nous l'explique Amaury). Dans mon cas, j'ai résolu le problème par des appels à time.sleep avec de petites valeurs (0.1 par exemple).
Franck
Comment pourrait on forcer son exécution alors que je n'ai pas de boucle
dans mon code principal (il existe une boucle qui attend les événements mais
je n'ai pas d'accès a son code et donc ne peux pas mettre de pause).
quelqu'un a t'il déjà eu ce type de problème ?
J'ai eu ce problème avec PyGTK dont la boucle d'événement semble garder
la main (ou le GIL comme nous l'explique Amaury). Dans mon cas, j'ai
résolu le problème par des appels à time.sleep avec de petites valeurs
(0.1 par exemple).
Comment pourrait on forcer son exécution alors que je n'ai pas de boucle dans mon code principal (il existe une boucle qui attend les événements mais je n'ai pas d'accès a son code et donc ne peux pas mettre de pause).
quelqu'un a t'il déjà eu ce type de problème ?
J'ai eu ce problème avec PyGTK dont la boucle d'événement semble garder la main (ou le GIL comme nous l'explique Amaury). Dans mon cas, j'ai résolu le problème par des appels à time.sleep avec de petites valeurs (0.1 par exemple).