Présentation du problème et pré-requis⚓
Fichier de pointages
Vous devez disposer d'un fichier contenant les pointages des positions au format csv avec les caractéristiques suivantes :
une ligne d'en-tête ;
séparateur de champs : le point-virgule ';'.
Vous pouvez télécharger trois exemples ici pour commencer à travailler :
Méthode : Obtention d'un fichier de pointages
L'obtention d'un fichier de pointages nécessite un logiciel permettant de pointer à la souris les positions successives d'un objet sur une vidéo.
Pymécavidéo est un logiciel libre, multiplate-formes (Windows, Linux).
Il est téléchargeable à cette adresse : Télécharger Pymécavidéo.
La vidéo ci-dessous reprend la procédure pour obtenir un fichier csv à l'aide de Pymécavidéo et de LibreOffice Calc.
Attention : Disposer d'un environnement de programmation Python
Pour réaliser cette activité il vous faut un environnement de programmation Python :
soit installé par vos soins du type Anaconda qui offre un environnement très complet quoiqu'un peu lourd ;
soit en récupérant un environnement autonome : Thonny Python (version Windows) qu'il suffit d'extraire et qui se lance en exécutant le fichier Thonny.exe dans le dossier une fois décompressé.
Ces environnements présentent l'avantage d'offrir un éditeur, une console et un explorateur de variables au sein de la même fenêtre.
Traitement du fichier avec un programme en Python⚓
Analyse du problème et programme à compléter
Question⚓
On donne ci-dessous le programme commenté à compléter pour obtenir le tracé des vecteurs vitesse et variation de vitesse.
Vous pourrez en faire un copier-coller dans votre éditeur Python en activant d'abord l'affichage en texte brut :
Le programme complété doit permettre d'obtenir :
les coordonnées des vecteurs vitesse ;
les coordonnées des vecteurs variation de vitesse.
On rappelle la définition du vecteur vitesse et la méthode de calcul sur un enregistrement :
avec
De même sur le vecteur variation de vitesse :
avec
Rappel sur le traitement des listes :
len(nom_liste) renvoie le nombre de termes d'une liste ;
avec numpy, pour ajouter un terme à une liste, on utilise la syntaxe liste = np.append(liste, terme à ajouter) ;
le premier terme d'une liste a pour indice 0 et le dernier len(liste)-1.
Questions :
Dans une boucle for, range(50) permet de faire varier l'indice de 0 à 49 : la valeur 50 n'est pas atteinte.
Pourquoi choisit-on len(t) - 1 dans la boucle à la ligne 48 du programme ?
Compléter le programme (lignes 49 et 50) de façon à obtenir les coordonnées du vecteur vitesse au point n°i.
À la ligne 53 du programme, pourquoi la borne devient len(t) - 2 ?
Compléter les lignes 54 et 55 de façon à calculer les valeurs des coordonnées du vecteur variation de vitesse au point n°i.
Une fois votre programme complété, testez-le avec un des fichiers csv proposés dans la partie Présentation du problème et pré-requis.
Pour travailler avec votre propre fichier de pointage, utilisez Pymécavidéo avec l'une des vidéos ci-dessous :
lancer d'une balle de golf (1,50 m entre les deux traits blancs)
véhicule sur un plan incliné (0,30 m pour la règle verticale)
from tkinter.filedialog import askopenfilename
import matplotlib.pyplot as plt
import numpy as np
# Ouverture en mode graphique d'un fichier de pointage au format CSV
# Ne pas modifier les lignes 7 à 17
name = askopenfilename(filetypes =(("Fichier CSV", "*.csv"),("Fichier Texte","*.txt"),("Tous les fichiers","*.*")),title = "Choisir un fichier")
sep = ";" # Caractère séparateur du csv (à adapter selon le fihcier csv utilisé, tabulation noté \t)
entete = 1 # Nombre de lignes d'entete (une ligne en général, à adapter sinon)
f = open(name,"r")
data = f.readlines() # Lecture de toutes les lignes et inscription dans la liste data
f.close() #on referme le fichier
data = data[ entete : ] # Suppression de la ligne d'en-tête qui ne nous intéressent pas
# On construit des listes nécessaires
t = np.array([])
x = np.array([])
y = np.array([])
vx = np.array([])
vy = np.array([])
Dvx = np.array([])
Dvy = np.array([])
# Traitement des données et répartition dans les listes t, x et y
# Ne pas modifier les lignes 31 à 38
for ligne in data:
ligne = ligne.replace("," , ".") # Séparateur décimal pour Python '.'
ligne = ligne.strip().split(sep) # Séparation des donnée
ligne = list(map(float,ligne)) # Conversion en décimal
# Répartition dans les listes créées précédemment
t = np.append(t, ligne[0])
x = np.append(x, ligne[1])
y = np.append(y, ligne[2])
dt = t[1] - t[0] # Détermination de l'intervalle de temps entre deux pointages
# Calcul des coordonnées des vecteurs vitesse
"""Complétez les champs indiqués afin de calculer :
- les coordonnées vx et vy au point n°i d'après la méthode vue en cours
- les coordonnnées Dvx et Dvy au point n°i d'après la méthode vue en cours"""
# Coordonnées vx et vy du vecteur vitesse
for i in range (len(t) - 1) :
vx = np.append(vx, """À COMPLÉTER""")
vy = np.append(vy, """A COMPLÉTER""")
# Coordonnées Dvx et Dvy du vecteur variation de vitesse
for i in range (len(t) - 2) :
Dvx = np.append(Dvx, """À COMPLÉTER""")
Dvy = np.append(Dvy, """À COMPLÉTER""")
# Obtention des tracés
# Adapter si besoin les échelles en ajustant la valeur scale
# Plus la valeur scale est faible, plus le vecteur est long et inversement.
plt.scatter(x, y, marker = "x", color = "blue", label = "Positions")
plt.quiver(x[:-1:], y[:-1:], vx, vy, units = "dots", color = "red", scale = 0.05, label = "Vecteurs vitesse")
plt.quiver(x[:-2:], y[:-2:], Dvx, Dvy, units = "dots", scale = 0.005, color = "green", label = "Vecteurs variation de vitesse")
plt.axis("equal")
plt.show()
plt.legend()
Solution⚓
Le dernier indice de la liste t a pour valeur len(t) - 1. range(len(t)) permet donc de parcourir l'ensemble de la liste or, le calcul de la vitesse au point i fait appel à la position au point i+1, donc il est impossible de faire le calcul de la vitesse pour le dernier point : on ne dispose pas de la position à l'instant suivant et le programme renvoie une erreur car on sort des dimensions de la liste.
Voir programme complété à la question 4.
Pour des raisons semblables à celles de la question 1 : la variation de vitesse n'est pas calculable pour la dernière valeur de la vitesse, ce qui exclut donc les deux derniers points de l'enregistrement des positions.
Voir programme complété ci-dessous.
1from tkinter.filedialog import askopenfilename
2import matplotlib.pyplot as plt
3import numpy as np
45#on peut donner le chemin d'accès vers le fichier ou la fonction askopenfilename
6name = askopenfilename(filetypes =(("Fichier CSV", "*.csv"),("Fichier Texte","*.txt"),("Tous les fichiers","*.*")),title = "Choisir un fichier")
78sep = ";" #caractère séparateur du csv -peut être une virgule, un point-virgule ou une tabulation noté \t
9entete = 1 #nombre de lignes d'entete
1011f = open(name,"r")
12data = f.readlines() #on lit toutes les lignes et on met ça dans une liste -un élément par ligne-
13f.close() #on referme le fichier
1415data = data[ entete : ] #on supprime les lignes d'en-tête qui ne nous intéressent pas
1617#on construit les listes de valeurs utiles
18t = np.array([])
19x = np.array([])
20y = np.array([])
21vx = np.array([])
22vy = np.array([])
23Dvx = np.array([])
24Dvy = np.array([])
2526for ligne in data:
27ligne = ligne.replace("," , ".") #change les virgules en point => format numérique différent sur excel et sur python
28ligne = ligne.strip().split(sep) #on sépare les différents élément en utilisant le caractère séparateur défini
29ligne = list(map(float,ligne)) #on converti chaque élément en flottant
30#on rentre les valeurs dans les listes adaptées
31t = np.append(t, ligne[0])
32x = np.append(x, ligne[1])
33y = np.append(y, ligne[2])
3435dt = t[1] - t[0] # Détermination de l'intervalle de temps entre deux pointages
36# Calcul des coordonnées des vecteurs vitesse
37for i in range (len(t) - 1) : # On ne peut pas calculer la dernière valeur de la vitesse (len(t) - 1)
38vx = np.append(vx, (x[i+1] - x[i]) / dt)
39vy = np.append(vy, (y[i+1] - y[i]) / dt)
4041for i in range (len(t) - 2) : # On ne peut pas calculer les deux dernières valeurs de Delta V (len(t) - 2
42Dvx = np.append(Dvx, vx[i+1] - vx[i])
43Dvy = np.append(Dvy, vy[i+1] - vy[i])
4445plt.scatter(x, y, marker = "x", color = "blue", label = "Positions")
46plt.quiver(x[:-1:], y[:-1:], vx, vy, units = "dots", color = "red", scale = 0.05, label = "Vecteurs vitesse")
47plt.quiver(x[:-2:], y[:-2:], Dvx, Dvy, units = "dots", scale = 0.005, color = "green", label = "Vecteurs variation de vitesse")
48plt.axis("equal")
49plt.show()
50plt.legend()
Ci-dessous le tracé obtenu avec le mouvement parabolique idéal (modélisé).
Ci-dessous, la procédure complète depuis l'obtention du fichier csv, jusqu'à son traitement par le programme Python complet.
Les paramètres d'échelle (scale) suivants permettent d'obtenir le tracé ci-dessous :
vecteur vitesse : \(scale=0.02\)
vecteur variation de vitesse : \(scale=0.0025\)
Le tracé du vecteur variation de vitesse est très sensible aux écarts de pointage, d'où quelques vecteurs incohérents sur la figure.
On peut cependant faire les deux observations suivantes :
sur le plan incliné, le vecteur variation de vitesse \(\Delta \vec v\) est dirigé selon la direction du plan incliné ;
sur la partie horizontale, le vecteur variation de vitesse est nul (aux imprécisions de pointage près) : le véhicule est en mouvement rectiligne uniforme.
Ci-dessous, le bilan des forces sur le plan incliné en négligeant toutes les forces de frottement (support et air).
La somme vectorielle \(\vec P + \vec R\) est parallèle au plan incliné, ce qui est conforme à la deuxième loi de Newton :
\(m \cdot \dfrac{\Delta \vec v}{\Delta t}=\vec P + \vec R\)