diff --git a/labyrinthe/4-arduino_pyserial/4 - Interfacer avec Arduino par pySerial.odp b/labyrinthe/4-arduino_pyserial/4 - Interfacer avec Arduino par pySerial.odp index 7bb8585..3ab0779 100644 Binary files a/labyrinthe/4-arduino_pyserial/4 - Interfacer avec Arduino par pySerial.odp and b/labyrinthe/4-arduino_pyserial/4 - Interfacer avec Arduino par pySerial.odp differ diff --git a/labyrinthe/4-arduino_pyserial/4 - Interfacer avec Arduino par pySerial.pdf b/labyrinthe/4-arduino_pyserial/4 - Interfacer avec Arduino par pySerial.pdf index a32d54b..eed06fd 100644 Binary files a/labyrinthe/4-arduino_pyserial/4 - Interfacer avec Arduino par pySerial.pdf and b/labyrinthe/4-arduino_pyserial/4 - Interfacer avec Arduino par pySerial.pdf differ diff --git a/labyrinthe/4-arduino_pyserial/4-labyrinthe.py b/labyrinthe/4-arduino_pyserial/4-labyrinthe.py index b43ebb8..dc081d2 100644 --- a/labyrinthe/4-arduino_pyserial/4-labyrinthe.py +++ b/labyrinthe/4-arduino_pyserial/4-labyrinthe.py @@ -98,7 +98,7 @@ def cycle(cont): obj = cont.owner # obj est l'objet associé au contrôleur donc 'Bille' obj['z']=obj.worldPosition.z # la propriété z est mis à jour avec la position globale en z de la bille - # Écriture de la position de la bille sur la liaison série : programme Arduino : 4-labyrinthe-imu.ino + # Écriture de la position de la bille sur la liaison série if obj['victoire']==False and obj['chute']==False: # obj['x'] = obj.worldPosition.x # de -3.5 à 3.5 # obj['y'] = obj.worldPosition.y # de 3.5 à -3.5 diff --git a/labyrinthe/5-microbit/5 - Interfacer avec microbit.odp b/labyrinthe/5-microbit/5 - Interfacer avec microbit.odp index 88ed6af..e48c24a 100644 Binary files a/labyrinthe/5-microbit/5 - Interfacer avec microbit.odp and b/labyrinthe/5-microbit/5 - Interfacer avec microbit.odp differ diff --git a/labyrinthe/5-microbit/5 - Interfacer avec microbit.pdf b/labyrinthe/5-microbit/5 - Interfacer avec microbit.pdf index d84ebcc..cd6bdf5 100644 Binary files a/labyrinthe/5-microbit/5 - Interfacer avec microbit.pdf and b/labyrinthe/5-microbit/5 - Interfacer avec microbit.pdf differ diff --git a/labyrinthe/5-microbit/5-labyrinthe-1.py b/labyrinthe/5-microbit/5-labyrinthe-1.py index 53796b0..b1826bd 100644 --- a/labyrinthe/5-microbit/5-labyrinthe-1.py +++ b/labyrinthe/5-microbit/5-labyrinthe-1.py @@ -24,7 +24,7 @@ JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED ACTIVATE = bge.logic.KX_INPUT_ACTIVE -# Communication avec la carte Arduino +# Communication avec la carte micro:bit # serial_baud=115200 # # serial_comm = serial.Serial('COM4',serial_baud, timeout=0.016) # Windows # serial_comm = serial.Serial('/dev/ttyACM1',serial_baud, timeout=0.016) # GNU/Linux @@ -54,7 +54,7 @@ def capteur(cont): serial_comm.close() bge.logic.endGame() - # Lecture de la liaison série : programme Arduino : 4-labyrinthe-imu.ino + # Lecture de la liaison série : programme micro:bit : 5-labyrinthe-microbit.py serial_msg_in = str(serial_comm.readline()) # Roll et Pitch diff --git a/labyrinthe/5-microbit/5-labyrinthe-2.py b/labyrinthe/5-microbit/5-labyrinthe-2.py new file mode 100644 index 0000000..a5b549a --- /dev/null +++ b/labyrinthe/5-microbit/5-labyrinthe-2.py @@ -0,0 +1,181 @@ +import bge # Bibliothèque Blender Game Engine (BGE) +import serial # Liaison série +import labyrinthe_carte # Liaison avec la carte + +############################################################################### +# 5-labyrinthe.py +# @title: Module (unique) de la scène 3D du labyrinthe à bille pilotable la centrale inertielle de la carte micro:bit +# @project: Blender-EduTech - Tutoriel 5 : Labyrinthe à bille - Interfacer avec une carte micro:bit +# @lang: fr +# @authors: Philippe Roy +# @copyright: Copyright (C) 2023 Philippe Roy +# @license: GNU GPL +# +# Commandes déclenchées par UPBGE pour le scène du labyrinthe +# +############################################################################### + +# Récupérer la scène 3D +scene = bge.logic.getCurrentScene() +# print("Objets de la scene : ", scene.objects) # Lister les objets de la scène + +# Constantes +JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED +JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED +ACTIVATE = bge.logic.KX_INPUT_ACTIVE + +# Communication avec la carte micro:bit +# serial_baud=115200 +# # serial_comm = serial.Serial('COM4',serial_baud, timeout=0.016) # Windows +# serial_comm = serial.Serial('/dev/ttyACM1',serial_baud, timeout=0.016) # GNU/Linux +# print (serial_comm) + +# Détection de la carte avec la liaison série +serial_comm = labyrinthe_carte.init_serial() +if serial_comm is None: + bge.logic.endGame() + +############################################################################### +# Gestion de la centrale inertielle de la carte micro:bit +# Les valeurs du capteur sont transmises de 0 à 1024 (10 bits) où 1024 -> 90°. +# Les valeurs de l'inclinaison du plateau dans UPBGE sont à fournir en radian. +############################################################################### + +# Lecture du capteur IMU +def capteur(cont): + obj = cont.owner # obj est l'objet associé au contrôleur donc 'Plateau' + obj_bille = scene.objects['Bille'] + echelle = 0.2 # Facteur d'échelle entre la capteur et la 3D + ecart=0.001 # Écart maxi sur la rotation + + # Touche ESC -> Quitter + keyboard = bge.logic.keyboard + if keyboard.inputs[bge.events.ESCKEY].status[0] == ACTIVATE: + serial_comm.close() + bge.logic.endGame() + + # Lecture de la liaison série : programme micro:bit : 5-labyrinthe-microbit.py + serial_msg_in = str(serial_comm.readline()) + + # Mettre la bille à la position de départ avec une vitesse nulle + if serial_msg_in.find("start")>0: + if obj_bille['victoire'] or obj_bille['chute']: + depart() + + # Roll et Pitch + if serial_msg_in.find(",")>0: + txt = serial_msg_in.split(',',2) + y_txt = txt[0][2:] + x_txt = txt[1][:-3] + # print (serial_msg_in, ":", x_txt,y_txt) + if x_txt != "" and y_txt != "": # Absence de valeur + x=(float(x_txt)/651.8) * echelle # 651.8 = 1024 / (pi/2) + y=(float(y_txt)/651.8) * echelle # 651.8 = 1024 / (pi/2) + while abs(x-obj.worldOrientation.to_euler().x) > ecart : + obj.applyRotation((x-obj.worldOrientation.to_euler().x, 0, -obj.worldOrientation.to_euler().z), False) + while abs(y-obj.worldOrientation.to_euler().y) > ecart : + obj.applyRotation((0, y-obj.worldOrientation.to_euler().y, -obj.worldOrientation.to_euler().z), False) + +############################################################################### +# Gameplay +############################################################################### + +# Initialisation de la scène +def init(cont): + obj = cont.owner # obj est l'objet associé au contrôleur donc 'Bille' + + # Mémorisation de la position de départ de la bille + obj['init_x']=obj.worldPosition.x + obj['init_y']=obj.worldPosition.y + obj['init_z']=obj.worldPosition.z + + # Cacher le panneau de la victoire et suspendre la physique du panneau cliquable + scene.objects['Panneau victoire'].setVisible(False,True) + scene.objects['Panneau victoire - plan'].suspendPhysics (True) + scene.objects['Bouton fermer'].color = (0, 0, 0, 1) # Noir + +# Cycle (boucle de contrôle de la bille) +def cycle(cont): + obj = cont.owner # obj est l'objet associé au contrôleur donc 'Bille' + obj['z']=obj.worldPosition.z # la propriété z est mis à jour avec la position globale en z de la bille + + # Écriture de la position de la bille sur la liaison série : programme micro:bit : 5-labyrinthe-microbit.py + if obj['victoire']==False and obj['chute']==False: + # obj['x'] = obj.worldPosition.x # de -3.5 à 3.5 + # obj['y'] = obj.worldPosition.y # de 3.5 à -3.5 + obj['Lx']=round((obj.worldPosition.x+3.5)*(4/7)) # de 0 à 4 + if obj['Lx']<0: obj['Lx']=0 + if obj['Lx']>4: obj['Lx']=4 + obj['Ly']=round((-obj.worldPosition.y+3.5)*(4/7)) # de 0 à 4 + if obj['Ly']<0: obj['Ly']=0 + if obj['Ly']>4: obj['Ly']=4 + serial_msg_out = str(obj['Lx'])+str(obj['Ly'])+"\n" + print (serial_msg_out) + serial_comm.write(serial_msg_out.encode()) + + # Si l'altitude de bille < -10 et pas de victoire -> chute + if obj['z'] < -10 and obj['victoire'] == False : + + # Afficher image de chute sur la matrice de leds + serial_msg_out = "91\n" + serial_comm.write(serial_msg_out.encode()) + obj['chute'] = True + +# Départ de la bille +def depart(): + obj_bille = scene.objects['Bille'] + obj_plateau = scene.objects['Plateau'] + + # Replacement du plateau (tous les angles à 0 en plusieurs fois) + while obj_plateau.worldOrientation.to_euler().x != 0 and obj_plateau.worldOrientation.to_euler().y !=0 and obj_plateau.worldOrientation.to_euler().z !=0 : + obj_plateau.applyRotation((-obj_plateau.worldOrientation.to_euler().x, -obj_plateau.worldOrientation.to_euler().y, -obj_plateau.worldOrientation.to_euler().z), False) + + # Mettre la bille à la position de départ avec une vitesse nulle + obj_bille.worldLinearVelocity=(0, 0, 0) + obj_bille.worldAngularVelocity=(0, 0, 0) + obj_bille.worldPosition.x = obj_bille['init_x'] + obj_bille.worldPosition.y = obj_bille['init_y'] + obj_bille.worldPosition.z = obj_bille['init_z']+0.5 # On repose la bille + obj_bille['victoire']=False + obj_bille['chute'] = False + +# Victoire (collision de la bille avec l'arrivée) +def victoire(cont): + + # # Afficher image de victoire sur la matrice de leds + serial_msg_out = "92\n" + serial_comm.write(serial_msg_out.encode()) + scene.objects['Bille']['victoire']=True + + # Animation du Panneau victoire + scene.objects['Panneau victoire'].setVisible(True,True) # Afficher le panneau de la victoire + scene.objects['Panneau victoire - plan'].restorePhysics() # Restaurer la physique du panneau cliquable + start = 1 + end = 100 + layer = 0 + priority = 1 + blendin = 1.0 + mode = bge.logic.KX_ACTION_MODE_PLAY + layerWeight = 0.0 + ipoFlags = 0 + speed = 1 + scene.objects['Panneau victoire'].playAction('Panneau victoireAction', start, end, layer, priority, blendin, mode, layerWeight, ipoFlags, speed) + +# Highlight du bouton Fermer +def victoire_fermer_hl(cont): + obj = cont.owner + + # Activation + if cont.sensors['MO'].status == JUST_ACTIVATED: + obj.color = (1, 1, 1, 1) # Blanc + + # Désactivation + if cont.sensors['MO'].status == JUST_RELEASED: + obj.color = (0, 0, 0, 1) # Noir + +# Fermer le panneau de la victoire (clic) +def victoire_fermer(cont): + if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive: + scene.objects['Panneau victoire'].setVisible(False,True) # Cacher le panneau de la victoire + scene.objects['Panneau victoire - plan'].suspendPhysics (True) # Suspendre la physique du panneau cliquable + depart() diff --git a/labyrinthe/5-microbit/5-labyrinthe.blend b/labyrinthe/5-microbit/5-labyrinthe.blend index bb68453..400343d 100644 Binary files a/labyrinthe/5-microbit/5-labyrinthe.blend and b/labyrinthe/5-microbit/5-labyrinthe.blend differ diff --git a/labyrinthe/5-microbit/5-labyrinthe.py b/labyrinthe/5-microbit/5-labyrinthe.py index 48fda8b..a567380 100644 --- a/labyrinthe/5-microbit/5-labyrinthe.py +++ b/labyrinthe/5-microbit/5-labyrinthe.py @@ -24,7 +24,7 @@ JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED ACTIVATE = bge.logic.KX_INPUT_ACTIVE -# Communication avec la carte Arduino +# Communication avec la carte micro:bit # serial_baud=115200 # # serial_comm = serial.Serial('COM4',serial_baud, timeout=0.016) # Windows # serial_comm = serial.Serial('/dev/ttyACM1',serial_baud, timeout=0.016) # GNU/Linux @@ -54,7 +54,7 @@ def capteur(cont): serial_comm.close() bge.logic.endGame() - # Lecture de la liaison série : programme Arduino : 4-labyrinthe-imu.ino + # Lecture de la liaison série : programme micro:bit : 5-labyrinthe-microbit.py serial_msg_in = str(serial_comm.readline()) # Mettre la bille à la position de départ avec une vitesse nulle @@ -99,7 +99,7 @@ def cycle(cont): obj = cont.owner # obj est l'objet associé au contrôleur donc 'Bille' obj['z']=obj.worldPosition.z # la propriété z est mis à jour avec la position globale en z de la bille - # Écriture de la position de la bille sur la liaison série : programme micro:bit : 5-labyrinthe-microbit.py + # Écriture de la position de la bille sur la liaison série if obj['victoire']==False and obj['chute']==False: # obj['x'] = obj.worldPosition.x # de -3.5 à 3.5 # obj['y'] = obj.worldPosition.y # de 3.5 à -3.5