Finalisation du moteur physique du monte-charge

This commit is contained in:
Philippe Roy 2022-12-22 05:02:33 +01:00
parent fdd0729f66
commit 62ca444e49
15 changed files with 285 additions and 283 deletions

View File

@ -2,10 +2,38 @@
Ce jumeau numérique permet la programmation en Python d'une maquette réelle d'un monte-charge. Ce jumeau numérique permet la programmation en Python d'une maquette réelle d'un monte-charge.
Le modèle 3D est basée sur la maquette développée par l'entreprise A4 technologie. Les documents techniques et pédagogiques signés A4 Technologie sont diffusés librement sous licence Creative Commons BY-NC-SA. ## Maquette numérique
Le modèle 3D est basé sur la maquette développée par l'entreprise A4 technologie. Les documents techniques et pédagogiques signés A4 Technologie sont diffusés librement sous licence Creative Commons BY-NC-SA.
Site internet de la maquette A4 Technologie : https://www.a4.fr/wiki/index.php?title=Monte_charge_(BE-MCHA) Site internet de la maquette A4 Technologie : https://www.a4.fr/wiki/index.php?title=Monte_charge_(BE-MCHA)
Ce jumeau numérique fait partie du projet open source Blender-EduTech (Blender/UPBGE pour l'Enseignement Technologique). ## Instructions
Site internet du projet Blender-EduTech : https://gitlab.com/blender-edutech/digital_twin Le script Python qui permet la commande du monte-charge est le fichier **'montchg_cmd.py'**. Il est éditable avec tout éditeur (Spyder, Emacs, Atom, ...).
#### Actions
Les actions (ordre = True ou False) sont :
- Monter la cabine (moteur sens trigo) : **mot_m (True | False)**
- Descendre la cabine (moteur sens horaire) : **mot_d (True | False)**
#### Capteurs
Les compte-rendus (valeur retournée = True ou False) des capteurs sont :
- Capteur présence cabine niveau 0 : **pc_0()**
- Capteur présence cabine niveau 1 : **pc_1()**
#### Pupitre
Les consignes (valeur retournée = True ou False) du pupitre sont :
- Bouton poussoir d'appel niveau 0 : **ba_0()**
- Bouton poussoir d'appel niveau 1: **ba_1()**
Les retours d'informations (allumer = True ou False) du pupitre sont :
- Voyant témoin d'étage niveau 0 : **voy_0()**
- Voyant témoin d'étage niveau 1 : **voy_1()**
#### Gestion du temps
Les temporisations : **tempo(duree)** avec la durée en seconde

View File

@ -55,212 +55,145 @@ def init(cont):
system_init() # Initialisation du système system_init() # Initialisation du système
###############################################################################
# Voyants
###############################################################################
##
# Etat voyant 0
# Modele 3d -> Arduino : FIXME
# Arduino -> Modele 3d : FIXME
##
def voy_0 (cont):
if scene.objects['System']['run']:
obj = cont.owner
if obj['activated'] and scene.objects['Led niveau 0-on'].visible == False:
scene.objects['Led niveau 0-on'].setVisible(True,False)
scene.objects['Led niveau 0'].setVisible(False,False)
if obj['activated']==False and scene.objects['Led niveau 0-on'].visible == True:
scene.objects['Led niveau 0'].setVisible(True,False)
scene.objects['Led niveau 0-on'].setVisible(False,False)
##
# Etat voyant 1
# Modele 3d -> Arduino : FIXME
# Arduino -> Modele 3d : FIXME
##
def voy_1 (cont):
if scene.objects['System']['run']:
obj = cont.owner
if obj['activated'] and scene.objects['Led niveau 1-on'].visible == False:
scene.objects['Led niveau 1-on'].setVisible(True,False)
scene.objects['Led niveau 1'].setVisible(False,False)
if obj['activated']==False and scene.objects['Led niveau 1-on'].visible == True:
scene.objects['Led niveau 1'].setVisible(True,False)
scene.objects['Led niveau 1-on'].setVisible(False,False)
############################################################################### ###############################################################################
# Actionneurs # Actionneurs
############################################################################### ###############################################################################
## ##
# Action du simulateur pour le moteur # Moteur et cabine
# Modele 3d -> Arduino : FIXME
# Arduino -> Modele 3d : FIXME
## ##
# def sml_moteur (cont): def mot (cont):
# if scene.objects['System']['run']: if scene.objects['System']['run']:
# obj = cont.owner obj = cont.owner
# pas_rot = math.pi/7 # z = 14 vitesse = 0.015
# pas = 2.35619/0.3 # pas echelle 1:1 = 2.35619 -> pas à l'échelle de la maquette (0,3) : 2.35619/0.3 = 7,85396 pas_cabine = 10 # Diam axe = 3 mm -> 1 tour = 3*math.pi
# vitesse = 0.05 pas_pignon = pas_cabine/(3*math.pi) # Z pignon = 48 dents
# engrenage_obj = scene.objects['Engrenage'] pas_vissansfin = pas_pignon*48
# portail_obj = scene.objects['Portail'] obj_vissansfin = scene.objects['Moteur vis sans fin']
# if obj['actif_ouvrir']: obj_pignon = scene.objects['Moteur pignon']
# # print (scene.objects['Portail'].worldPosition.x) obj_cabine = scene.objects['Cabine']
# engrenage_obj.applyRotation((0, 0, -pas_rot*vitesse), True) obj_cabine['z']= scene.objects['Cabine'].localPosition.z # Affichage de l'altitude de la cabine
# portail_obj.applyMovement((-pas*vitesse, 0, 0), True) obj_contrepoids = scene.objects['Contrepoids']
# # else: obj_cable = scene.objects['Cable'] # FIXME : plus tard
# if obj['actif_fermer']: if obj['up']:
# # print (scene.objects['Portail'].worldPosition.x) obj_vissansfin.applyRotation((0, 0, pas_vissansfin*vitesse), True)
# engrenage_obj.applyRotation((0, 0, pas_rot*vitesse), True) obj_pignon.applyRotation((pas_pignon*vitesse, 0, 0), True)
# portail_obj.applyMovement((pas*vitesse, 0, 0), True) obj_cabine.applyMovement((0, 0, pas_cabine*vitesse), True)
obj_contrepoids.applyMovement((0, 0, -pas_cabine*vitesse), True)
# else: # Pas de priorité
if obj['down']:
obj_vissansfin.applyRotation((0, 0, -pas_vissansfin*vitesse), True)
obj_pignon.applyRotation((-pas_pignon*vitesse, 0, 0), True)
obj_cabine.applyMovement((0, 0, -pas_cabine*vitesse), True)
obj_contrepoids.applyMovement((0, 0, pas_cabine*vitesse), True)
############################################################################### ###############################################################################
# Capteurs fin de course # Capteurs
############################################################################### ###############################################################################
## ##
# Etat capteur fin de course portail ouvert # Etat capteur présence cabine niveau 0
# Modele 3d -> Arduino : FIXME
# Arduino -> Modele 3d : FIXME
## ##
# def sml_fdc_ouvert (cont): def pc_0 (cont):
# if scene.objects['System']['run'] : if scene.objects['System']['run'] :
# obj = cont.owner obj = cont.owner
# obj_etat=obj['actif']
# obj_microrupteur=scene.objects['Microrupteur fdc ouvert'] # Etat capteur en fonction de la position de la cabine : localPosition.z entre -40 et -42
# # Etat capteur en fonction de la grille : worldPosition.x : 0 -> 65.5 et localPosition.x : 0 -> 218 if scene.objects['Cabine'].localPosition.z <-40 and scene.objects['Cabine'].localPosition.z >-42 and obj['activated'] == False :
# if scene.objects['Portail'].localPosition.x <= 0 and obj['actif'] == False : obj['activated'] = True
# obj['actif'] = True if (scene.objects['Cabine'].localPosition.z > -40 or scene.objects['Cabine'].localPosition.z <-42) and obj['activated'] == True :
# if scene.objects['Portail'].localPosition.x > 0 and obj_microrupteur['actif'] == False and obj['actif'] == True : obj['activated'] = False
# obj['actif'] = False
# #Forçage # Forçage (click)
# if obj_microrupteur['actif'] == True: if obj['click'] == True:
# obj['actif'] = True obj['activated'] = True
# #Couleurs
# if obj['actif'] == True and obj_microrupteur.color !=couleur_jaune: # Couleurs
# obj_microrupteur.color =couleur_jaune if obj['activated'] == True and obj.color !=color_activated:
# if obj['actif'] == False : obj.color =color_activated
# if obj_microrupteur['MO'] == True and obj_microrupteur.color !=couleur_blanc: if obj['activated'] == False :
# obj_microrupteur.color =couleur_blanc if obj['mo'] == True and obj.color !=color_hl:
# if obj_microrupteur['MO'] == False and obj_microrupteur.color !=couleur_orange: obj.color =color_hl
# obj_microrupteur.color =couleur_orange if obj['mo'] == False and obj.color !=color_active:
obj.color =color_active
## ##
# Etat capteur fin de course portail fermé # Etat capteur présence cabine niveau 1
# Modele 3d -> Arduino : FIXME
# Arduino -> Modele 3d : FIXME
## ##
# def sml_fdc_ferme (cont): def pc_1 (cont):
# if scene.objects['System']['run'] : if scene.objects['System']['run'] :
# obj = cont.owner obj = cont.owner
# obj_etat=obj['actif']
# obj_microrupteur=scene.objects['Microrupteur fdc ferme'] # Etat capteur en fonction de la position de la cabine : localPosition.z entre 0 et -2
# # Etat capteur en fonction de la grille : worldPosition.x : 0 -> 65.5 et localPosition.x : 0 -> 218 if scene.objects['Cabine'].localPosition.z <0 and scene.objects['Cabine'].localPosition.z >-2 and obj['activated'] == False :
# if scene.objects['Portail'].localPosition.x >= 218 and obj['actif'] == False : obj['activated'] = True
# obj['actif'] = True if (scene.objects['Cabine'].localPosition.z > 0 or scene.objects['Cabine'].localPosition.z <-2) and obj['activated'] == True :
# if scene.objects['Portail'].localPosition.x < 218 and obj_microrupteur['actif'] == False and obj['actif'] == True : obj['activated'] = False
# obj['actif'] = False
# #Forçage # Forçage (click)
# if obj_microrupteur['actif'] == True: if obj['click'] == True:
# obj['actif'] = True obj['activated'] = True
# #Couleurs
# if obj['actif'] == True and obj_microrupteur.color !=couleur_jaune: # Couleurs
# obj_microrupteur.color =couleur_jaune if obj['activated'] == True and obj.color !=color_activated:
# if obj['actif'] == False : obj.color =color_activated
# if obj_microrupteur['MO'] == True and obj_microrupteur.color !=couleur_blanc: if obj['activated'] == False :
# obj_microrupteur.color =couleur_blanc if obj['mo'] == True and obj.color !=color_hl:
# if obj_microrupteur['MO'] == False and obj_microrupteur.color !=couleur_orange: obj.color =color_hl
# obj_microrupteur.color =couleur_orange if obj['mo'] == False and obj.color !=color_active:
obj.color =color_active
############################################################################### ###############################################################################
# Système # Boutons
############################################################################### ###############################################################################
## # Modele 3d -> Arduino : FIXME
# Initialisation du système # Arduino -> Modele 3d : FIXME
# # Le moteur est géré en continue.
##
def system_init ():
system_reset()
##
# Réinitialisation du système
##
def system_reset ():
# Voyants aux états initiaux
scene.objects['Led niveau 0'].setVisible(True,False)
scene.objects['Led niveau 0-on'].setVisible(False,False)
scene.objects['Led niveau 1'].setVisible(True,False)
scene.objects['Led niveau 1-on'].setVisible(False,False)
# Cabine
# # applyRotationTo(scene.objects['System'], 0, 0, 0)
scene.objects['Cabine'].worldPosition.x = scene.objects['Cabine']['init_lx']
scene.objects['Cabine'].worldPosition.y = scene.objects['Cabine']['init_ly']
scene.objects['Cabine'].worldPosition.z = scene.objects['Cabine']['init_lz']
scene.objects['Contrepoids'].worldPosition.x = scene.objects['Contrepoids']['init_lx']
scene.objects['Contrepoids'].worldPosition.y = scene.objects['Contrepoids']['init_ly']
scene.objects['Contrepoids'].worldPosition.z = scene.objects['Contrepoids']['init_lz']
# # Moteur à l'état initial
# rres=0.001 # resolution rotation
# obj1=scene.objects['Engrenage']
# while (obj1.localOrientation.to_euler().y) > 1.1*rres :
# obj1.applyRotation((0, 0, -rres), True)
# while (obj1.localOrientation.to_euler().y) < -1.1*rres :
# obj1.applyRotation((0, 0, rres), True)
# I/O à l'état initial
scene.objects['Led niveau 0']['activated']=False
scene.objects['Led niveau 1']['activated']=False
scene.objects['Bp niveau 0']['activated']=False
scene.objects['Bp niveau 1']['activated']=False
scene.objects['Microrupteur niveau 0']['activated']=False
scene.objects['Microrupteur niveau 1']['activated']=False
##
# Boucle principale
##
def system_run ():
# # Lecture de la liaison série : programme Arduino : berceau_arduino.ino
# serial_msg = str(serial_comm.readline()) # Communication série : arduino -> modele 3d
# # Affiche le message uniquement
# if serial_msg.find("Print")>0 or serial_msg.find("Debug")>0 or serial_msg.find("Echo")>0:
# print ("Communication port série : ", serial_msg)
# serial_msg=""
# return
# Voyant niveau 0
# Modele 3d -> Arduino : FIXME
# Arduino -> Modele 3d : FIXME
if scene.objects['Led niveau 0']['activated']==True and scene.objects['Led niveau 0-on'].visible == False:
scene.objects['Led niveau 0-on'].setVisible(True,False)
scene.objects['Led niveau 0'].setVisible(False,False)
if scene.objects['Led niveau 0']['activated']==False and scene.objects['Led niveau 0-on'].visible == True:
scene.objects['Led niveau 0'].setVisible(True,False)
scene.objects['Led niveau 0-on'].setVisible(False,False)
# Voyant niveau 1
# Modele 3d -> Arduino : FIXME
# Arduino -> Modele 3d : FIXME
if scene.objects['Led niveau 1']['activated']==True and scene.objects['Led niveau 1-on'].visible == False:
scene.objects['Led niveau 1-on'].setVisible(True,False)
scene.objects['Led niveau 1'].setVisible(False,False)
if scene.objects['Led niveau 1']['activated']==False and scene.objects['Led niveau 1-on'].visible == True:
scene.objects['Led niveau 1'].setVisible(True,False)
scene.objects['Led niveau 1-on'].setVisible(False,False)
# Moteur et cabine
# Modele 3d -> Arduino : FIXME
# Arduino -> Modele 3d : FIXME
obj = cont.owner
pas_rot = math.pi/7 # z = 14
pas = 2.35619/0.3 # pas echelle 1:1 = 2.35619 -> pas à l'échelle de la maquette (0,3) : 2.35619/0.3 = 7,85396
vitesse = 0.05
obj_moteur = scene.objects['Moteur']
obj_vissansfin = scene.objects['Moteur vis sans fin']
obj_pignon = scene.objects['Moteur pignon']
obj_cabine = scene.objects['Cabine']
obj_contrepoids = scene.objects['Contrepoids']
obj_cable = scene.objects['Cable']
if obj_moteur['up']:
# print (scene.objects['Portail'].worldPosition.x)
obj_cabine.applyMovement((0, 0, pas*vitesse), True)
# engrenage_obj.applyRotation((0, 0, -pas_rot*vitesse), True)
# else:
if obj_moteur['down']:
# print (scene.objects['Portail'].worldPosition.x)
obj_cabine.applyMovement((0, 0, -pas*vitesse), True)
# engrenage_obj.applyRotation((0, 0, pas_rot*vitesse), True)
# print ("serial_msg : ", serial_msg)
# roll_txt = txt_extrac(serial_msg,"Roll (Rx): ", " Pitch")
# # pitch_txt= txt_extrac(serial_msg,"Pitch (Ry): ", " \\r\\n")
# pitch_txt = txt_extrac(serial_msg,"Pitch (Ry): ", " bt_a_m:")
# if roll_txt !="" and pitch_txt !="" :
# obj1=scene.objects['Plateau']
# roll=float(roll_txt)/57.3
# pitch=float(pitch_txt)/57.3
# # print ("Roll : ", roll, " Pitch : ", pitch)
# applyRotationTo(scene.objects['Plateau'], roll,0, 0)
# applyRotationTo(scene.objects['Plateau'], roll,pitch, 0)
# scene.objects['Plateau']['roll']=roll
# scene.objects['Plateau']['pitch']=pitch
# Capteurs
# Modele 3d -> Arduino : FIXME
# Arduino -> Modele 3d : FIXME
# Arduino -> numérique # Arduino -> numérique
# bt_a_m_txt = txt_extrac_bool(serial_msg,"bt_a_m: ") # bt_a_m_txt = txt_extrac_bool(serial_msg,"bt_a_m: ")
@ -288,44 +221,44 @@ def system_run ():
# obj.color = couleur_orange # obj.color = couleur_orange
############################################################################### ###############################################################################
# Interface # Système
############################################################################### ###############################################################################
## ##
# Highlight sur les éléments cliquables du systèmes # Initialisation du système
# # Le moteur est géré en continue.
## ##
def hl(cont): def system_init ():
obj = cont.owner system_reset()
name=obj.name
# Activation
if cont.sensors['MO'].status == JUST_ACTIVATED and scene.objects['System']['run']:
scene.objects[name].color = color_hl
# Désactivation
if cont.sensors['MO'].status == JUST_RELEASED:
scene.objects[name].color = color_active
## ##
# Click sur les éléments cliquables du systèmes (activation numérique) # Réinitialisation du système
## ##
def click(cont): def system_reset ():
obj = cont.owner
name=obj.name
# Activation # Voyants aux états initiaux
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['System']['manip_mode']==0: scene.objects['Led niveau 0'].setVisible(True,False)
scene.objects[name].color = color_activated scene.objects['Led niveau 0-on'].setVisible(False,False)
obj['activated'] = True scene.objects['Led niveau 1'].setVisible(True,False)
# Modele 3d -> Arduino : FIXME scene.objects['Led niveau 1-on'].setVisible(False,False)
# Désactivation # Cabine
if cont.sensors['Click'].status == JUST_RELEASED: # applyRotationTo(scene.objects['System'], 0, 0, 0)
obj['activated'] = False scene.objects['Cabine'].worldPosition.x = scene.objects['Cabine']['init_lx']
# Modele 3d -> Arduino : FIXME scene.objects['Cabine'].worldPosition.y = scene.objects['Cabine']['init_ly']
if cont.sensors['MO'].positive: scene.objects['Cabine'].worldPosition.z = scene.objects['Cabine']['init_lz']
scene.objects[name].color = color_hl scene.objects['Contrepoids'].worldPosition.x = scene.objects['Contrepoids']['init_lx']
else: scene.objects['Contrepoids'].worldPosition.y = scene.objects['Contrepoids']['init_ly']
scene.objects[name].color = color_active scene.objects['Contrepoids'].worldPosition.z = scene.objects['Contrepoids']['init_lz']
# Moteur à l'état initial : pas utile
# I/O à l'état initial
scene.objects['Led niveau 0']['activated']=False
scene.objects['Led niveau 1']['activated']=False
scene.objects['Bp niveau 0']['activated']=False
scene.objects['Bp niveau 1']['activated']=False
scene.objects['Microrupteur niveau 0']['activated']=False
scene.objects['Microrupteur niveau 1']['activated']=False

View File

@ -9,19 +9,21 @@ from montchg_lib import * # Bibliothèque portail coulissant
# Instructions élémentaires pour le monte-charge # Instructions élémentaires pour le monte-charge
# #
# Actions (ordre = True ou False) : # Actions (ordre = True ou False) :
# - Allumer voyant niveau 0 : voy_0 (True|False) # - Monter le monte-charge (moteur sens trigo) : mot_m (True | False)
# - Allumer voyant niveau 1 : voy_1 (True|False) # - Descendre le monte-charge (moteur sens horaire) : mot_d (True | False)
# - Monter le monte-charge (moteur sens trigo) : mot_m (True|False)
# - Descendre le monte-charge (moteur sens horaire) : mot_d (True|False)
# #
# Capteurs (valeur retournée = True ou False) : # Capteurs (valeur retournée = True ou False) :
# - Capteur présence cabine niveau 0 : pc_0() # - Capteur présence cabine niveau 0 : pc_0()
# - Capteur présence cabine niveau 1 : pc_1() # - Capteur présence cabine niveau 1 : pc_1()
# #
# Pupitre (valeur retournée = True ou False) : # Les consigne du pupitre (valeur retournée = True ou False) :
# - Bouton poussoir appel niveau 0 : ba_0() # - Bouton poussoir appel niveau 0 : ba_0()
# - Bouton poussoir appel niveau 1 : ba_1() # - Bouton poussoir appel niveau 1 : ba_1()
# #
# Les retours d'informations du pupitre (allumer = True ou False) :
# - Voyant témoin d'étage niveau 0 : voy_0 (True | False)
# - Voyant témoin d'étage niveau 1 : voy_1 (True | False)
#
# Gestion du temps : # Gestion du temps :
# - Temporisation en seconde : tempo(duree) # - Temporisation en seconde : tempo(duree)
# #
@ -42,9 +44,21 @@ def commandes():
print ("Ok go !!") print ("Ok go !!")
# Ecrire votre code ici ... # Ecrire votre code ici ...
voy_0(True) # Activer le voyant du niveau 0
while True: while True:
pass
if ba_0()==True:
voy_1(False)
voy_0(True)
mot_m(False)
mot_d(True)
if ba_1()==True:
voy_0(False)
voy_1(True)
mot_d(False)
mot_m(True)
# pass
fin() # A garder fin() # A garder

View File

@ -29,15 +29,7 @@ board = None
board_it = None # Iterator (input) board_it = None # Iterator (input)
# Brochage du jumeau numérique # Brochage du jumeau numérique
bp_int_pin = None # FIXME
bp_ext_pin = None
fdc_o_pin = None
fdc_f_pin = None
ir_emett_pin = None
ir_recept_pin = None
mot_o_pin = None
mot_f_pin = None
gyr_pin = None
# UPBGE constants # UPBGE constants
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
@ -129,8 +121,6 @@ def end():
# Jumeau numérique # Jumeau numérique
if scene.objects['System']['twins']: if scene.objects['System']['twins']:
# serial_msg = "FI\n"
# twins_serial.write(serial_msg.encode()) # Communication série : modele 3d -> carte communication ( arduino | micro:bit )
jumeau_close() jumeau_close()
# Thread # Thread
@ -147,42 +137,28 @@ def quit():
end() end()
############################################################################### ###############################################################################
# Actionneurs # Voyants
############################################################################### ###############################################################################
# Ordre pour le voyant 0 # Ordre pour le voyant 0
def voy_0 (order): def voy_0 (order):
scene.objects['Led niveau 0']['activated']=order scene.objects['Led niveau 0']['activated']=order
# if order:
# scene.objects['Led niveau 0-on'].setVisible(True,False)
# scene.objects['Led niveau 0'].setVisible(False,False)
# else:
# scene.objects['Led niveau 0'].setVisible(True,False)
# scene.objects['Led niveau 0-on'].setVisible(False,False)
# global gyr_pin
# if scene.objects['System']['twins'] :
# if ordre :
# gyr_pin.write(1)
# else:
# gyr_pin.write(0)
# Ordre pour le voyant 1 # Ordre pour le voyant 1
def voy_1 (order): def voy_1 (order):
scene.objects['Led niveau 1']['activated']=order scene.objects['Led niveau 1']['activated']=order
# if order:
# scene.objects['Led niveau 1-on'].setVisible(True,False) ###############################################################################
# scene.objects['Led niveau 1'].setVisible(False,False) # Actionneurs
# else: ###############################################################################
# scene.objects['Led niveau 1'].setVisible(True,False)
# scene.objects['Led niveau 1-on'].setVisible(False,False)
# Ordre pour le moteur phase monter # Ordre pour le moteur phase monter
def mot_m (order): def mot_m (order):
scene.objects['Led niveau 1']['up']=order scene.objects['Moteur']['up']=order
# Ordre pour le moteur phase descendre # Ordre pour le moteur phase descendre
def mot_d (order): def mot_d (order):
scene.objects['Ensemble moteur']['down']=ordre scene.objects['Moteur']['down']=order
############################################################################### ###############################################################################
# Capteurs # Capteurs
@ -346,7 +322,7 @@ def jumeau_close():
scene.objects['System']['twins'] = False scene.objects['System']['twins'] = False
scene.objects['Twins-text']['Text'] = "Connection fermée." scene.objects['Twins-text']['Text'] = "Connection fermée."
# Configuration du port # Configuration manuelle du port
# FIXME # FIXME
def jumeau_config(port, speed): def jumeau_config(port, speed):
pass pass

Binary file not shown.

View File

@ -2,11 +2,13 @@
Ce jumeau numérique permet la programmation en Python d'une maquette réelle d'un portail coulissant. Ce jumeau numérique permet la programmation en Python d'une maquette réelle d'un portail coulissant.
## Maquette numérique
Le modèle 3D est basé sur la maquette développée par l'entreprise A4 technologie. Les documents techniques et pédagogiques signés A4 Technologie sont diffusés librement sous licence Creative Commons BY-NC-SA. Le modèle 3D est basé sur la maquette développée par l'entreprise A4 technologie. Les documents techniques et pédagogiques signés A4 Technologie sont diffusés librement sous licence Creative Commons BY-NC-SA.
Site internet de la maquette A4 Technologie : https://www.a4.fr/wiki/index.php?title=Portail_coulissant_(BE-APORT-COUL) Site internet de la maquette A4 Technologie : https://www.a4.fr/wiki/index.php?title=Portail_coulissant_(BE-APORT-COUL)
## Instructions et missions ## Instructions
Le script Python qui permet la commande du portail est le fichier **'porcou_cmd.py'**. Il est éditable avec tout éditeur (Spyder, Emacs, Atom, ...). Le script Python qui permet la commande du portail est le fichier **'porcou_cmd.py'**. Il est éditable avec tout éditeur (Spyder, Emacs, Atom, ...).
@ -14,15 +16,15 @@ Le script Python qui permet la commande du portail est le fichier **'porcou_cmd.
Les actions (ordre = True ou False) sont : Les actions (ordre = True ou False) sont :
- Gyrophare : **gyr (True|False)** - Gyrophare : **gyr (True|False)**
- Ouvrir le portail (moteur sens trigo) : **mot_o (True|False)** - Ouvrir le portail (moteur sens trigo) : **mot_o (True | False)**
- Fermer le portail (moteur sens horaire) : **mot_f (True|False)** - Fermer le portail (moteur sens horaire) : **mot_f (True | False)**
- Emetteur pour le capteur barrage IR : **ir_emet(True|False)** - Emetteur pour le capteur barrage IR : **ir_emet(True | False)**
#### Capteurs #### Capteurs
Les compte-rendus (valeur retournée = True ou False) des capteurs sont : Les compte-rendus (valeur retournée = True ou False) des capteurs sont :
- Capteur fin de course portail ouvert : **fc_o()** - Capteur fin de course portail ouvert : **fdc_o()**
- Capteur fin de course portail fermé : **fc_f()** - Capteur fin de course portail fermé : **fdc_f()**
- Capteur barrage IR (absence d'obstacle) : **ir_recep()** - Capteur barrage IR (absence d'obstacle) : **ir_recep()**
#### Pupitre #### Pupitre

View File

@ -19,14 +19,12 @@ import time
scene = bge.logic.getCurrentScene() scene = bge.logic.getCurrentScene()
# Couleurs # Couleurs
couleur_magenta = (0.800, 0.005, 0.315,1) # bouton non activable : magenta couleur_magenta = (0.800, 0.005, 0.315,1) # bouton non activable : magenta
couleur_orange = (0.799, 0.130, 0.063,1) # bouton activable : orange couleur_orange = (0.799, 0.130, 0.063,1) # bouton activable : orange
couleur_blanc = (0.8, 0.8, 0.8, 1) # bouton focus : blanc couleur_blanc = (0.8, 0.8, 0.8, 1) # bouton focus : blanc
couleur_jaune = (0.8, 0.619, 0.021, 1) # bouton activé : jaune couleur_jaune = (0.8, 0.619, 0.021, 1) # bouton activé : jaune
# Constantes UPBGE # Constantes UPBGE
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED
ACTIVATE = bge.logic.KX_INPUT_ACTIVE ACTIVATE = bge.logic.KX_INPUT_ACTIVE
@ -113,10 +111,10 @@ def sml_fdc_ouvert (cont):
obj['actif'] = True obj['actif'] = True
if scene.objects['Portail'].localPosition.x > 0 and obj_microrupteur['actif'] == False and obj['actif'] == True : if scene.objects['Portail'].localPosition.x > 0 and obj_microrupteur['actif'] == False and obj['actif'] == True :
obj['actif'] = False obj['actif'] = False
#Forçage # Forçage
if obj_microrupteur['actif'] == True: if obj_microrupteur['actif'] == True:
obj['actif'] = True obj['actif'] = True
#Couleurs # Couleurs
if obj['actif'] == True and obj_microrupteur.color !=couleur_jaune: if obj['actif'] == True and obj_microrupteur.color !=couleur_jaune:
obj_microrupteur.color =couleur_jaune obj_microrupteur.color =couleur_jaune
if obj['actif'] == False : if obj['actif'] == False :

61
twin.py
View File

@ -21,6 +21,7 @@ import twin_about # About
# @license: GNU GPL # @license: GNU GPL
# #
# Cet environnement 3D est programmable en Python. Il est destiné à la découverte de la programmation de système pluritechnologique. # Cet environnement 3D est programmable en Python. Il est destiné à la découverte de la programmation de système pluritechnologique.
#
############################################################################### ###############################################################################
# UPBGE scene # UPBGE scene
@ -32,7 +33,6 @@ sys.setrecursionlimit(10**5) # Limite sur la récursivité (valeur par défaut
# EEVEE # EEVEE
eevee = bpy.context.scene.eevee eevee = bpy.context.scene.eevee
# fps_time=0.0
# Config file # Config file
twin_config = ET.parse('twin_config.xml') twin_config = ET.parse('twin_config.xml')
@ -41,6 +41,10 @@ twin_config_tree = twin_config.getroot()
# Couleurs # Couleurs
color_cmd = (0.8, 0.8, 0.8, 1) # Blanc color_cmd = (0.8, 0.8, 0.8, 1) # Blanc
color_cmd_hl = (0.8, 0.619, 0.021, 1) # Jaune color_cmd_hl = (0.8, 0.619, 0.021, 1) # Jaune
color_passive = (0.800, 0.005, 0.315,1) # bouton non activable : magenta
color_active = (0.799, 0.130, 0.063,1) # bouton activable : orange
color_hl = (0.8, 0.8, 0.8, 1) # bouton focus : blanc
color_activated = (0.8, 0.619, 0.021, 1) # bouton activé : jaune
# Constantes # Constantes
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
@ -130,13 +134,13 @@ def cmd_init():
scene.objects['ResetView-Hl'].setVisible(False,False) scene.objects['ResetView-Hl'].setVisible(False,False)
scene.objects['Doc-cmd-Hl'].setVisible(False,False) scene.objects['Doc-cmd-Hl'].setVisible(False,False)
scene.objects['About-cmd-Hl'].setVisible(False,False) scene.objects['About-cmd-Hl'].setVisible(False,False)
scene.objects['Twins-icon'].setVisible(False,True) # scene.objects['Twins-icon'].setVisible(False,True)
# UI : Text, ... # UI : Text, ...
scene.objects['Cmd-text']['Text']="" scene.objects['Cmd-text']['Text']=""
scene.objects['Cmd-text'].setVisible(True,False) scene.objects['Cmd-text'].setVisible(True,False)
scene.objects['Twins-text']['Text']="Connection fermée." scene.objects['Twins-text']['Text']="Connection fermée."
scene.objects['Twins-text'].setVisible(False,False) # scene.objects['Twins-text'].setVisible(False,False)
# Windows # Windows
windows=("Doc", "Doc_chap-general", "Doc_chap-system", "Doc_chap-python", "About") windows=("Doc", "Doc_chap-general", "Doc_chap-system", "Doc_chap-python", "About")
@ -440,7 +444,7 @@ def manip_wheel(cont):
## ##
# Mise en route et pause du cycle # Validation du code Python
## ##
def python_validation(file): def python_validation(file):
@ -461,6 +465,10 @@ def python_validation(file):
scene.objects['Cmd-text'].setVisible(False,False) scene.objects['Cmd-text'].setVisible(False,False)
return True return True
##
# Mise en route et pause du cycle
##
def cycle_run (): def cycle_run ():
# Pause # Pause
@ -492,7 +500,7 @@ def cycle_run ():
# Arrêt de la pause # Arrêt de la pause
else: else:
# FIXME : Relancer Ropy # FIXME : Relancer la maquette
pass pass
## ##
@ -519,3 +527,46 @@ def cycle_end (cont):
scene.objects['Pause-Hl'].setVisible(False,False) scene.objects['Pause-Hl'].setVisible(False,False)
scene.objects['Run'].setVisible(True,False) scene.objects['Run'].setVisible(True,False)
scene.objects['Run'].restorePhysics() scene.objects['Run'].restorePhysics()
##
# Highlight sur les éléments cliquables du systèmes
##
def cycle_hl(cont):
obj = cont.owner
name=obj.name
# Activation
if cont.sensors['MO'].status == JUST_ACTIVATED and scene.objects['System']['run']:
scene.objects[name].color = color_hl
scene.objects[name]['mo'] = True
# Désactivation
if cont.sensors['MO'].status == JUST_RELEASED:
scene.objects[name].color = color_active
scene.objects[name]['mo'] = False
##
# Click sur les éléments cliquables du systèmes (activation numérique)
##
def cycle_click(cont):
obj = cont.owner
name=obj.name
# Activation
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['System']['manip_mode']==0:
scene.objects[name].color = color_activated
obj['activated'] = True
obj['click'] = True
# Modele 3d -> Arduino : FIXME
# Désactivation
if cont.sensors['Click'].status == JUST_RELEASED:
obj['activated'] = False
obj['click'] = False
# Modele 3d -> Arduino : FIXME
if cont.sensors['MO'].positive:
scene.objects[name].color = color_hl
else:
scene.objects[name].color = color_active

View File

@ -36,6 +36,7 @@ ACTIVATE = bge.logic.KX_INPUT_ACTIVE
## ##
def open(): def open():
scene.objects['System']['manip_mode']=9 # Fenêtre modale About
scene.active_camera = scene.objects["Camera-About"] scene.active_camera = scene.objects["Camera-About"]
# scene.removeOverlayCollection(bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay # scene.removeOverlayCollection(bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay
scene.objects['Twins-icon'].setVisible(False,True) # Crash de UPBGE sur la supression de l'Overlay scene.objects['Twins-icon'].setVisible(False,True) # Crash de UPBGE sur la supression de l'Overlay
@ -72,6 +73,7 @@ def open():
def close(cont): def close(cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive : if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
scene.objects['System']['manip_mode']=0 # Enlever la fenêtre modale
scene.active_camera = scene.objects["Camera"] scene.active_camera = scene.objects["Camera"]
# scene.addOverlayCollection(scene.cameras['Camera-Hud'], bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay # scene.addOverlayCollection(scene.cameras['Camera-Hud'], bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay
scene.objects['Twins-icon'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay scene.objects['Twins-icon'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay

View File

@ -1,6 +1,6 @@
<data> <data>
<screen> <screen>
<width>1339</width> <width>1458</width>
<height>753</height> <height>821</height>
</screen> </screen>
</data> </data>

View File

@ -232,6 +232,7 @@ def open():
init() init()
# Placer la tablette # Placer la tablette
scene.objects['System']['manip_mode']=8 # Fenêtre modale Documentation
scene.active_camera = scene.objects["Camera-Doc"] scene.active_camera = scene.objects["Camera-Doc"]
# scene.removeOverlayCollection(bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay # scene.removeOverlayCollection(bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay
scene.objects['Twins-icon'].setVisible(False,True) # Crash de UPBGE sur la supression de l'Overlay scene.objects['Twins-icon'].setVisible(False,True) # Crash de UPBGE sur la supression de l'Overlay
@ -280,6 +281,7 @@ def open():
def close(cont): def close(cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive : if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
scene.objects['System']['manip_mode']=0 # Enlever la fenêtre modale
scene.active_camera = scene.objects["Camera"] scene.active_camera = scene.objects["Camera"]
# scene.addOverlayCollection(scene.cameras['Camera-Hud'], bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay # scene.addOverlayCollection(scene.cameras['Camera-Hud'], bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay
scene.objects['Twins-icon'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay scene.objects['Twins-icon'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay

Binary file not shown.

View File

@ -11,22 +11,18 @@ import time
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr> # @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL # @license: GNU GPL
#
# Commandes déclenchées par/sur le simulateur (sml_*)
############################################################################### ###############################################################################
# Récupérer la scène UPBGE # Récupérer la scène UPBGE
scene = bge.logic.getCurrentScene() scene = bge.logic.getCurrentScene()
# Couleurs # Couleurs
color_passive = (0.800, 0.005, 0.315,1) # bouton non activable : magenta
couleur_magenta = (0.800, 0.005, 0.315,1) # bouton non activable : magenta color_active = (0.799, 0.130, 0.063,1) # bouton activable : orange
couleur_orange = (0.799, 0.130, 0.063,1) # bouton activable : orange color_hl = (0.8, 0.8, 0.8, 1) # bouton focus : blanc
couleur_blanc = (0.8, 0.8, 0.8, 1) # bouton focus : blanc color_activated = (0.8, 0.619, 0.021, 1) # bouton activé : jaune
couleur_jaune = (0.8, 0.619, 0.021, 1) # bouton activé : jaune
# Constantes UPBGE # Constantes UPBGE
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED
ACTIVATE = bge.logic.KX_INPUT_ACTIVE ACTIVATE = bge.logic.KX_INPUT_ACTIVE

View File

@ -1,4 +1,4 @@
from volroul_lib import * # Bibliothèque volet roulant from volrou_lib import * # Bibliothèque volet roulant
############################################################################### ###############################################################################
# volrou_cmd.py # volrou_cmd.py