Génération de fichier de données CSV suite

This commit is contained in:
Philippe Roy 2023-01-21 06:56:54 +01:00
parent e3f0f9dd1d
commit e456346d3a
18 changed files with 306 additions and 54 deletions

View File

@ -48,6 +48,8 @@ def commandes():
voy_0(False)
print ("")
daq(['mot_angle', 'mot_vitesse', 'cabine_z', 'cabine_vitesse'])
# Monter
mot_digitset (500)
t0,z0, a0= get('t'), get('cabine_z'), get('mot_angle')

View File

@ -12,7 +12,7 @@
# Documentation du système
################################################################################
system_card=["twins-card", "pin-card", "data-card", "plot-card", "movement-card", "board-card", "model-card", "firmata-card", "arduino-card"]
system_card=["twins-card", "pin-card", "data-card", "daq-card", "movement-card", "board-card", "model-card", "firmata-card", "arduino-card"]
system_card_description ={}
# Jumeau numérique
@ -45,20 +45,22 @@ card_data_title="Accès aux données"
card_data_text=""" get(variable) \n -> Retourne la valeur de la variable à \n l'instant t. Par exemple : val = get('ba_0').\n
Entrées/sorties : 'ba_0', 'ba_1', 'pc_0', 'pc_1', \n 'mot_m', 'mot_d', 'voy_0' et 'voy_1'.\n
Variables réels (si il y a jumelage) : 'ba_0_r', \n 'ba_1_r', 'pc_0_r', 'pc_1_r'.\n
Autres variables : 't' (temps), 'mot_angle', 'mot_vitesse', \n 'cabine_z'."""
Autres variables : 't' (temps), 'mot_angle', \n 'mot_vitesse', 'cabine_z'."""
card_data_url=[]
system_card_description.update({"data-card" : [card_data_title, card_data_text, card_data_url]})
# Monitoring
card_plot_title="Acquisition de données"
card_plot_text=""" plot([variables]) \n -> Affiche le chronogramme des variables \n spécifiées.
Par exemple : plot(['ba_0', 'cabine_z']).\n
csv([variables]) \n -> Déclenche l'acquisition de données afin \n de génèrer un fichier de données CSV à \n l'arrêt du cycle.\n
card_daq_title="Acquisition de données"
# card_daq_text="aaa"+"\u2192"+"ddd"
card_daq_text=""" daq([variables]) \n -> Déclenche l'acquisition de données afin \n de génèrer un fichier de données CSV à \n l'arrêt du cycle.
Par exemple : daq(['ba_0', 'cabine_z']).\n
plot() \n Affiche le chronogramme à l'arrêt du
cycle. Le chronogramme interactif est en \n cours d'implémentation.\n
Les variables pouvant être suivies sont les \n mêmes que celles de la page "Données"."""
# Blender étant cadencé à 60 fps, la fréquence \n d'acquisition est 16 ms."""
card_plot_url=[["Bibliothèque Matplotlib","https://matplotlib.org/"],
["Wikipedia Français : fichier CSV","https://fr.wikipedia.org/wiki/Comma-separated_values"]]
system_card_description.update({"plot-card" : [card_plot_title, card_plot_text, card_plot_url]})
card_daq_url=[["Wikipedia Français : fichier CSV","https://fr.wikipedia.org/wiki/Comma-separated_values"],
["Bibliothèque Matplotlib","https://matplotlib.org/"]]
system_card_description.update({"daq-card" : [card_daq_title, card_daq_text, card_daq_url]})
# Ouvrir et fermer
card_movement_title="Monter et descendre"

View File

@ -1,7 +1,7 @@
import bge # Bibliothèque Blender Game Engine (UPBGE)
from twin_threading import thread_cmd_start, thread_cmd_stop, thread_cmd_end # Multithreading
from twin_serial import jumeau, jumeau_stop, serial_close # Liaison série
from twin_plot import plot, get # Visualisation des données
from twin_daq import get, daq, csv_generate, plot, plot_generate # Acquisition des données
import time
###############################################################################
@ -94,14 +94,16 @@ def ba_1 ():
# Cycle
###############################################################################
##
# Temporisation
##
def tempo (duree):
time.sleep(duree)
##
# t (temps)
def truncate(n, decimals=0):
multiplier = 10**decimals
return int(n* multiplier)/multiplier
##
def get_t ():
# return truncate(scene.objects['System']['time'], 3)
@ -113,20 +115,46 @@ def set_t (date):
def reset_t ():
scene.objects['System']['time']=0
##
# Arrêt
##
def stop():
# Jumeau
if scene.objects['System']['twins']:
serial_close(scene.objects['System']['board'])
time.sleep(1)
scene.objects['System']['plot_draw']=False
# Suivi de données
if scene.objects['System']['daq']:
csv_generate()
if scene.objects['System']['plot']:
plot_generate()
scene.objects['System']['plot_draw']=False # Plot
# Thread
thread_cmd_stop()
##
# Fin naturelle
##
def end():
# Jumeau
if scene.objects['System']['twins']:
serial_close(scene.objects['System']['board'])
time.sleep(1)
scene.objects['System']['plot_draw']=False
# Suivi de données
if scene.objects['System']['daq']:
csv_generate()
if scene.objects['System']['plot']:
plot_generate()
scene.objects['System']['plot_draw']=False # Plot
# Thread
thread_cmd_end()
def fin():
@ -134,4 +162,3 @@ def fin():
def quit():
end()

Binary file not shown.

1
monte_charge/twin_daq.py Symbolic link
View File

@ -0,0 +1 @@
/home/phroy/Bureau/seriousgames/blender-edutech/git/digital_twin/twin_daq.py

1
poppy_ergo_jr/twin_daq.py Symbolic link
View File

@ -0,0 +1 @@
/home/phroy/Bureau/seriousgames/blender-edutech/git/digital_twin/twin_daq.py

View File

@ -47,6 +47,8 @@ def commandes():
gyr(False)
print ("")
daq(['mot_angle', 'mot_vitesse', 'portail_x', 'portail_vitesse'])
# Fermeture
mot_digitset (1256) # Vitesse par défaut 125,6 rad /s ( 20 tr / s )
t0,x0, a0= get('t'), get('portail_x'), get('mot_angle')

View File

@ -14,7 +14,7 @@
# Documentation du système
################################################################################
system_card=["twins-card", "pin-card", "data-card", "plot-card", "movement-card", "sensor-card", "gyro-card", "board-card", "model-card", "firmata-card", "arduino-card"]
system_card=["twins-card", "pin-card", "data-card", "daq-card", "movement-card", "sensor-card", "gyro-card", "board-card", "model-card", "firmata-card", "arduino-card"]
system_card_description ={}
# Jumeau numérique
@ -52,15 +52,17 @@ card_data_url=[]
system_card_description.update({"data-card" : [card_data_title, card_data_text, card_data_url]})
# Monitoring
card_plot_title="Acquisition de données"
card_plot_text=""" plot([variables]) \n -> Affiche le chronogramme des variables \n spécifiées.
Par exemple : plot(['bp_ext', 'portail_x']).\n
csv([variables]) \n -> Déclenche l'acquisition de données afin \n de génèrer un fichier de données CSV à \n l'arrêt du cycle.\n
card_daq_title="Acquisition de données"
# card_daq_text="aaa"+"\u2192"+"ddd"
card_daq_text=""" daq([variables]) \n -> Déclenche l'acquisition de données afin \n de génèrer un fichier de données CSV à \n l'arrêt du cycle.
Par exemple : daq(['bp_ext', 'portail_x']).\n
plot() \n Affiche le chronogramme à l'arrêt du
cycle. Le chronogramme interactif est en \n cours d'implémentation.\n
Les variables pouvant être suivies sont les \n mêmes que celles de la page "Données"."""
# Blender étant cadencé à 60 fps, la fréquence \n d'acquisition est 16 ms."""
card_plot_url=[["Bibliothèque Matplotlib","https://matplotlib.org/"],
["Wikipedia Français : fichier CSV","https://fr.wikipedia.org/wiki/Comma-separated_values"]]
system_card_description.update({"plot-card" : [card_plot_title, card_plot_text, card_plot_url]})
card_daq_url=[["Wikipedia Français : fichier CSV","https://fr.wikipedia.org/wiki/Comma-separated_values"],
["Bibliothèque Matplotlib","https://matplotlib.org/"]]
system_card_description.update({"daq-card" : [card_daq_title, card_daq_text, card_daq_url]})
# Ouvrir et fermer
card_movement_title="Ouvrir et fermer"

View File

@ -1,7 +1,7 @@
import bge # Bibliothèque Blender Game Engine (UPBGE)
from twin_threading import thread_cmd_start, thread_cmd_stop, thread_cmd_end # Multithreading (multitâches)
from twin_serial import jumeau, jumeau_stop, serial_close # Liaison série
from twin_plot import plot, get # Visualisation des données
from twin_daq import get, daq, csv_generate, plot, plot_generate # Acquisition des données
import time
###############################################################################
@ -102,14 +102,16 @@ def bp_int ():
# Cycle
###############################################################################
##
# Temporisation
##
def tempo (duree):
time.sleep(duree)
##
# t (temps)
def truncate(n, decimals=0):
multiplier = 10**decimals
return int(n* multiplier)/multiplier
##
def get_t ():
# return truncate(scene.objects['System']['time'], 3)
@ -121,20 +123,46 @@ def set_t (date):
def reset_t ():
scene.objects['System']['time']=0
##
# Arrêt
##
def stop():
# Jumeau
if scene.objects['System']['twins']:
serial_close(scene.objects['System']['board'])
time.sleep(1)
scene.objects['System']['plot_draw']=False
# Suivi de données
if scene.objects['System']['daq']:
csv_generate()
if scene.objects['System']['plot']:
plot_generate()
scene.objects['System']['plot_draw']=False # Plot
# Thread
thread_cmd_stop()
##
# Fin naturelle
##
def end():
# Jumeau
if scene.objects['System']['twins']:
serial_close(scene.objects['System']['board'])
time.sleep(1)
scene.objects['System']['plot_draw']=False
# Suivi de données
if scene.objects['System']['daq']:
csv_generate()
if scene.objects['System']['plot']:
plot_generate()
scene.objects['System']['plot_draw']=False # Plot
# Thread
thread_cmd_end()
def fin():
@ -142,4 +170,3 @@ def fin():
def quit():
end()

View File

@ -0,0 +1 @@
/home/phroy/Bureau/seriousgames/blender-edutech/git/digital_twin/twin_daq.py

View File

@ -1,7 +1,7 @@
<data>
<screen>
<width>1590</width>
<height>895</height>
<width>1609</width>
<height>905</height>
<quality>1</quality>
</screen>
</data>

170
twin_daq.py Normal file
View File

@ -0,0 +1,170 @@
import bge # Bibliothèque Blender Game Engine (UPBGE)
import os
import sys
import importlib
import subprocess # Multiprocessus
import time
import csv
###############################################################################
# twin_daq.py
# @title: Enregistement et visualisation des données
# @project: Blender-EduTech
# @lang: fr
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2023 Philippe Roy
# @license: GNU GPL
###############################################################################
# UPBGE scene
scene = bge.logic.getCurrentScene()
# Récupérer la configuration du graphique
system=importlib.import_module(scene.objects['System']['system']) # Système
daq_config = system.get_public_vars()
# CSV
daq_data=[]
###############################################################################
# Accès aux variables publiques du système
###############################################################################
def get(data):
if data in daq_config:
if len (daq_config[data][0])>2: # Echelle à prendre en compte
return(scene.objects[daq_config[data][0][0]][daq_config[data][0][1]]*daq_config[data][0][2])
else:
return(scene.objects[daq_config[data][0][0]][daq_config[data][0][1]])
else:
print ("Erreur sur l'accès aux variables par get("+data+"), la variable '"+data+"' absente du système.")
return None
###############################################################################
# Enregistrement des données
###############################################################################
# Démarage et configuration des variables
def daq(data):
scene.objects['System']['daq_var'] =[]
data_line = ['t']
for var in data:
scene.objects['System']['daq_var'].append([daq_config[var][0][0], daq_config[var][0][1]])
data_line.append(var)
print ("Acquisition des données :", scene.objects['System']['daq_var'])
daq_data.append(data_line)
scene.objects['System']['daq']=True
# Ajout des données (fps = 60)
def daq_add(cont):
data_line = [round(scene.objects['System']['time'], 3)]
for var in scene.objects['System']['daq_var']:
data_line.append(round(scene.objects[var[0]][var[1]], 3))
daq_data.append(data_line)
###############################################################################
# Tableau CSV
###############################################################################
# Format français des décimaux
def localize_floats(row):
return [
str(el).replace('.', ',') if isinstance(el, float) else el
for el in row
]
# Génération du fichier
def csv_generate():
scene.objects['System']['daq']=False
fichier_csv=scene.objects['System']['system']+'.csv'
print ("Génération du fichier :", fichier_csv)
scene.objects['Cmd-text']['Text']= "Génération du fichier :", fichier_csv
with open(fichier_csv, 'w') as csvfile:
writer = csv.writer(csvfile, delimiter = ';', lineterminator = '\n')
for t_data in daq_data:
writer.writerow(localize_floats(t_data))
###############################################################################
# Graphique statique
###############################################################################
# Génération du fichier
def plot_generate():
pass
###############################################################################
# Graphique interactif
# FIXME : ne marche pas
###############################################################################
# Mise en forme de décimaux
def truncate(n, decimals=0):
multiplier = 10**decimals
return int(n* multiplier)/multiplier
# Création du graphique interactif
def plot(data):
# subprocess.run([sys.executable, os.path.join(os.getcwd(), "twin_plot.py")], , stdin=subprocess.PIPE) # Process bloquant
# Terminer le processus précédent
if scene.objects['System']['plot_proc'] is not None:
if scene.objects['System']['plot_proc'].poll()==None:
scene.objects['System']['plot_proc'].terminate()
scene.objects['System']['plot_draw'] = True
scene.objects['System']['plot_time'] = 0
# Configuration des données
scene.objects['System']['plot_data'] =[]
for obj in data:
scene.objects['System']['plot_data'].append(daq_config[obj][0][0])
# Démarrer le processus
scene.objects['System']['plot_proc'] = subprocess.Popen([sys.executable, os.path.join(os.getcwd(), "twin_plot_qt.py")], stdin=subprocess.PIPE, encoding = 'utf8', universal_newlines=True)
# # scene.objects['System']['plot_proc'] = subprocess.Popen([sys.executable, os.path.join(os.getcwd(), "twin_plot_qt.py")], stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding = 'utf8')
# # stout = scene.objects['System']['plot_proc'].communicate() # FIXME : attente du message retour pour lancer l'acquisition
# # print("Blender stout : ", stout)
scene.objects['System']['plot']=True
# Ajout des données (fps = 60)
def plot_add(cont):
if cont.sensors['Plot'].positive :
# Affichage du graphique
if scene.objects['System']['plot_draw']:
if scene.objects['System']['plot_time'] != truncate(scene.objects['System']['time'], 0) or True:
# Préparation du message
# FIXME : ajouter les valeurs réelles et valeurs numériques ('activated_real')
scene.objects['System']['plot_time'] = truncate(scene.objects['System']['time'], 0)
# msg=str(round(scene.objects['System']['plot_time'], 1))
# msg=format(scene.objects['System']['plot_time'],".2f")
msg=format(scene.objects['System']['plot_time'],".2f")
for obj in scene.objects['System']['plot_data']:
if scene.objects[obj]['activated']:
msg = msg+",1"
else:
msg = msg+",0"
msg = msg+"\n"
# Envoi (Pipe)
if scene.objects['System']['plot_proc'].poll()==None:
# # scene.objects['System']['plot_proc'].communicate(input=time_send.encode())[0] # Communication bloquante
# scene.objects['System']['plot_proc'].communicate(input=msg.encode())[0] # Communication bloquante
scene.objects['System']['plot_proc'].communicate(input=msg.encode()) # Communication bloquante
# scene.objects['System']['plot_proc'].stdin.write(msg)
print ("twin : ", msg)
else:
# Arrêt
print ("Stop")
scene.objects['System']['plot']=False
scene.objects['System']['plot_draw'] =False
scene.objects['System']['plot_proc'].terminate()
# Arrêt de l'affichage du graphique
if scene.objects['System']['plot_proc'].poll()==None:
pass
else:
print ("Stop")
scene.objects['System']['plot']=False
scene.objects['System']['plot_draw'] =False
scene.objects['System']['plot_proc'].terminate()

1
volet_roulant/twin_daq.py Symbolic link
View File

@ -0,0 +1 @@
/home/phroy/Bureau/seriousgames/blender-edutech/git/digital_twin/twin_daq.py

Binary file not shown.

View File

@ -41,7 +41,7 @@ from volrou_lib import * # Bibliothèque utilisateur du volet roulant
def commandes():
csv_start(['mot_angle'])
daq(['mot_angle'])
# Init -> Descendre
while fdc_b() ==False :

View File

@ -12,7 +12,7 @@
# Documentation du système
################################################################################
system_card=["twins-card", "pin-card", "data-card", "plot-card", "movement-card", "sensor-card", "board-card", "model-card", "firmata-card", "arduino-card"]
system_card=["twins-card", "pin-card", "data-card", "daq-card", "movement-card", "sensor-card", "board-card", "model-card", "firmata-card", "arduino-card"]
system_card_description ={}
# Jumeau numérique
@ -49,16 +49,18 @@ card_data_text=""" get(variable) \n -> Retourne la valeur de la variable à \n l
card_data_url=[]
system_card_description.update({"data-card" : [card_data_title, card_data_text, card_data_url]})
# Monitoring
card_plot_title="Acquisition de données"
card_plot_text=""" plot([variables]) \n -> Affiche le chronogramme des variables \n spécifiées.
Par exemple : plot(['bp_m', 'moteur_angle']).\n
csv([variables]) \n -> Déclenche l'acquisition de données afin \n de génèrer un fichier de données CSV à \n l'arrêt du cycle.\n
# Monitoring
card_daq_title="Acquisition de données"
# card_daq_text="aaa"+"\u2192"+"ddd"
card_daq_text=""" daq([variables]) \n -> Déclenche l'acquisition de données afin \n de génèrer un fichier de données CSV à \n l'arrêt du cycle.
Par exemple : daq(['bp_ext', 'portail_x']).\n
plot() \n \u2192 Affiche le chronogramme à l'arrêt du
cycle. Le chronogramme interactif est en \n cours d'implémentation.\n
Les variables pouvant être suivies sont les \n mêmes que celles de la page "Données"."""
# Blender étant cadencé à 60 fps, la fréquence \n d'acquisition est 16 ms."""
card_plot_url=[["Bibliothèque Matplotlib","https://matplotlib.org/"],
["Wikipedia Français : fichier CSV","https://fr.wikipedia.org/wiki/Comma-separated_values"]]
system_card_description.update({"plot-card" : [card_plot_title, card_plot_text, card_plot_url]})
card_daq_url=[["Wikipedia Français : fichier CSV","https://fr.wikipedia.org/wiki/Comma-separated_values"],
["Bibliothèque Matplotlib","https://matplotlib.org/"]]
system_card_description.update({"daq-card" : [card_daq_title, card_daq_text, card_daq_url]})
# Ouvrir et fermer
card_movement_title="Monter et descendre"

View File

@ -1,7 +1,7 @@
import bge # Bibliothèque Blender Game Engine (UPBGE)
from twin_threading import thread_cmd_start, thread_cmd_stop, thread_cmd_end # Multithreading
from twin_serial import jumeau, jumeau_stop, serial_close # Liaison série
from twin_plot import get, csv_start, csv_generate, plot # Visualisation des données
from twin_daq import get, daq, csv_generate, plot, plot_generate # Acquisition des données
import time
###############################################################################
@ -106,14 +106,16 @@ def bp_auto ():
# Cycle
###############################################################################
##
# Temporisation
##
def tempo (duree):
time.sleep(duree)
##
# t (temps)
def truncate(n, decimals=0):
multiplier = 10**decimals
return int(n* multiplier)/multiplier
##
def get_t ():
# return truncate(scene.objects['System']['time'], 3)
@ -125,7 +127,10 @@ def set_t (date):
def reset_t ():
scene.objects['System']['time']=0
##
# Arrêt
##
def stop():
# Jumeau
@ -134,12 +139,19 @@ def stop():
time.sleep(1)
# Suivi de données
if scene.objects['System']['csv']:
if scene.objects['System']['daq']:
csv_generate()
scene.objects['System']['plot_draw']=False # Plot
thread_cmd_stop() # Thread
if scene.objects['System']['plot']:
plot_generate()
scene.objects['System']['plot_draw']=False # Plot
# Thread
thread_cmd_stop()
##
# Fin naturelle
##
def end():
# Jumeau
@ -148,15 +160,17 @@ def end():
time.sleep(1)
# Suivi de données
if scene.objects['System']['csv']:
if scene.objects['System']['daq']:
csv_generate()
if scene.objects['System']['plot']:
plot_generate()
scene.objects['System']['plot_draw']=False # Plot
scene.objects['System']['plot_draw']=False # Plot
thread_cmd_end() # Thread
# Thread
thread_cmd_end()
def fin():
end()
def quit():
end()