Etude des rebonds d'une balle¶

© J.Roussel | 2023-11-15

L'expérience consiste à laisser tomber la balle d'une hauteur initiale $h_0$ dans le champ de pesanteur terrestre $\overrightarrow{g}$ puis d'enregistrer à l'aide d'un smartphone posé sur un sol horizontal le son produit par les différentes collisions.

Pour en savoir plus, voir mesurer g avec un smartphone

Chargement des bibliothèques

In [1]:
import numpy as np
import math
from numpy import random as rnd
import scipy.optimize as spo
import matplotlib.pyplot as plt   

Procédure permettant d'écrire les résultats au format Y = (valeur ± incertitude) x10^n unité

In [2]:
def ecriture(name_variable,unit,x,dx) :
    if dx>0:
        n=math.floor(math.log10(dx))
    elif deltaY<0: 
        n=math.floor(math.log10(-dx))
    else :
        n=0
    chaine1="{:." + str(1) + "f}"
    chaine2=name_variable +" = (" + chaine1 + " ± " + chaine1 + ")x{:.0E}"+" {}"
    chaine3=name_variable +" = (" + chaine1 + " ± " + chaine1 + ") {}"
    if n==0:
        print(chaine3.format(x/10**n,dx/10**n,unit))
    else:
        print(chaine2.format(x/10**n,dx/10**n,10**n,unit))

Données expérimentales¶

On utilise une bille de masse $m=25$ g et de diamètre $D=35$ mm. La hauteur de chute vaut $h_0=869$ mm

In [3]:
h_0=0.869
Delta_h0=1E-3/np.sqrt(3) # incertitude à 95% nc
D=.035
m=25E-3

Les durées des rebonds sont stockés dans un fichiers CSV.

Pour obtenir l'enregistrement sonore, voir mesurer g avec un smartphone

In [4]:
fichier = open('./data/rebonds.csv', 'r')
donnees = np.loadtxt(fichier,delimiter=',')
x = donnees[:,0]     # numéro du rebond
ux = donnees[:,1]    # incertitude (ici nulle)
T = donnees[:,2]     # Durée du rebond
uT = donnees[:,3]    # incertiude-type

Traitement des données¶

Création de nouvelles variables¶

On définit $Y=ln(T_n)$ ou $T_n$ est la durée du n-ième rebond

In [5]:
y=np.log(T)
uy=uT/T
print(y)
[-0.26657311 -0.36240562 -0.45728486 -0.55512588 -0.64626359 -0.73396918]

Regression linéaire¶

Théoriquement on prévoit $\ln{T_n}=an+b$ avec $a=\ln(\varepsilon)$ et $b=\ln(2T_0)$.

Définition du modèle

In [6]:
def f(x,p):
    a,b=p
    return a*x+b

La méthode des moindres carrés pondérés consiste à minimiser le $\chi^2=\sum_k \frac{[y_k-f(x_k)]^2}{u(y_k)^2}$. Dans scipy, il faut définir l'erreur $\frac{[y_k-f(x_k)]}{u(y_k)}$

In [7]:
def cout1(p, y, x):
    return (y-f(x,p))/uy

Initialisation des paramètres (pour aider la convergence)

In [8]:
p0=np.array([-.1,-.2])

Méthode des moindres carrés par l'algorithme de Levenberg-Marquardt

In [9]:
resultat=spo.leastsq(cout1, p0, args=(y,x), full_output=True)
plt.scatter(x, y)
xx=np.linspace(min(x),max(x),100)
plt.plot(xx,f(xx,resultat[0]),label='Modélisation')
plt.errorbar(x,y, yerr=2*uy,fmt='.',label='Mesures')
plt.legend()
plt.grid()
plt.title('Ajustement de la loi $\\ln(T_n)=a n + b$ aux données \n par la méthode des moindres carrés pondérés',)
plt.ylabel('$\\ln(T_n)$')
plt.xlabel('$n$')
Out[9]:
Text(0.5, 0, '$n$')

La loi est vérifiée.

Écriture des résultats¶

In [10]:
tStudent=2.57 #pour élargir à niveau de confiance de 95%
A=resultat[0][0]
DeltaA=tStudent*np.sqrt(np.diagonal(resultat[1])[0])
ecriture("a","",A,DeltaA)
B=resultat[0][1]
DeltaB=tStudent*np.sqrt(np.diagonal(resultat[1])[1])
ecriture("b","",B,DeltaB)
a = (-942.6 ± 8.2)x1E-04 
b = (-173.8 ± 2.8)x1E-03 

Théoriquement on en déduit le temps de chute $T_0=\frac12 \mathrm{e}^{b}$ et le coefficient de restitution $\varepsilon=\mathrm{e}^a$.

In [11]:
restitution=np.exp(A)
DeltaE=restitution*DeltaA
T_0=.5*np.exp(B)
DeltaT=T_0*DeltaB
ecriture("𝜺","",restitution,DeltaE)
ecriture("T0","s",T_0,DeltaT)
𝜺 = (9100.4 ± 7.4)x1E-04 
T0 = (420.2 ± 1.2)x1E-03 s

On en déduit le champ de pesanteur $g=\frac{2h_0}{T_0^2}$

In [12]:
g=2*h_0/(T_0**2)
DeltaG=g*np.sqrt((Delta_h0/h_0)**2+(2*DeltaB)**2)
ecriture("g","m/s^2",g,DeltaG)
g = (984.1 ± 5.5)x1E-02 m/s^2

Correction de l'effet des frottements¶

In [13]:
rho_air=1.2
Cx=0.47
TT=T/(1-rho_air*np.pi*D**2*Cx*g*T**2/(128*m))
print(TT)
[0.76901192 0.69825781 0.63469757 0.57526516 0.52496215 0.48073934]

Calcul de $g$ à partir des nouvelles valeurs de $T_n$. On répète la méthode précédente.

In [14]:
y=np.log(TT)
uy=uT/T
p0=np.array([-.1,-.2])
resultat=spo.leastsq(cout1, p0, args=(y,x), full_output=True)
tStudent=2.57 
A=resultat[0][0]
DeltaA=tStudent*np.sqrt(np.diagonal(resultat[1])[0])
ecriture("a","",A,DeltaA)
B=resultat[0][1]
DeltaB=tStudent*np.sqrt(np.diagonal(resultat[1])[1])
ecriture("b","",B,DeltaB)
restitution=np.exp(A)
DeltaE=restitution*DeltaA
T_0=.5*np.exp(B)
DeltaT=T_0*DeltaB
ecriture("𝜺","",restitution,DeltaE)
ecriture("T0","s",T_0,DeltaT)
g=8*h_0/np.exp(2*B)
DeltaG=g*np.sqrt((Delta_h0/h_0)**2+(2*DeltaB)**2)
ecriture("g","m/s^2",g,DeltaG)
a = (-947.6 ± 8.2)x1E-04 
b = (-169.5 ± 2.8)x1E-03 
𝜺 = (9095.9 ± 7.4)x1E-04 
T0 = (422.1 ± 1.2)x1E-03 s
g = (975.7 ± 5.5)x1E-02 m/s^2

Correction de la poussée d'Archimède¶

In [15]:
rho=m/(np.pi*D**3/6)
pesanteur=g/(1-rho_air/(rho))
ecriture("Résultat final : g","m/s^2",pesanteur,DeltaG)
Résultat final : g = (976.7 ± 5.5)x1E-02 m/s^2