Tutoriels guidés
Piloter la catapulte avec Python
La même catapulte, écrite en dix lignes de vrai code — et ce qu'un script peut, et ne peut pas, piloter.
Le script
Voici la catapulte du tutoriel, écrite avec l'API réelle du labo. Un clic sur Construire dans le labo, puis Play, puis efface le verrou rouge (clic, Suppr).
# LA CATAPULTE DU TUTORIEL — la version Python de ce qu'on construit a la main.
import math
scene.vider()
RAIDEUR = 120 # N/m : le ressort
TENSION = 40 # mm : de combien il est deja tendu quand le bras est arme
ARME = -20 # degres : l'angle du bras quand il est retenu par le verrou
TIR = 50 # degres : l'angle ou la butee arrete le bras
VERROU = True # False : pas de verrou, ca tire des le Play
# 1. la base
SOL_Y = 300
sol(x=0, y=SOL_Y, largeur=3000, hauteur=40, materiau="pierre")
PX, PY = -200, 40 # le haut du poteau : l'axe du bras
poteau = rectangle(x=PX, y=(PY + SOL_Y - 20) / 2, largeur=30, hauteur=SOL_Y - 20 - PY,
fixe=True, materiau="pierre", couleur="#64748b")
def sur_le_bras(dx, dy, angle=ARME):
"""Le point (dx, dy) du bras : dx le long du bras depuis l'axe (negatif = vers
la cuillere, positif = vers la queue), dy en travers (negatif = au-dessus)."""
a = math.radians(angle)
return (PX + dx * math.cos(a) - dy * math.sin(a), PY + dx * math.sin(a) + dy * math.cos(a))
# 2. le bras, et le fond de la cuillere soude a son bout
bx, by = sur_le_bras(-40, 0)
bras = rectangle(x=bx, y=by, largeur=260, hauteur=10, angle=ARME, materiau="bois", couleur="#a16207")
fx, fy = sur_le_bras(-167, -15)
fond = rectangle(x=fx, y=fy, largeur=6, hauteur=26, angle=ARME, materiau="bois", couleur="#a16207")
pivot(x=fx, y=fy, corps=[bras, fond], soude=True, contact=False)
# 3. le pivot
pivot(x=PX, y=PY, corps=[bras, poteau], contact=False)
# 4. la propulsion : le ressort (accroche a 50 mm de l'axe, crochet defini dans la pose de TIR), la butee, le verrou
qx, qy = sur_le_bras(90, 0, TIR)
ressort(a=(bras, 90, 0), b=(qx, qy + 150), raideur=RAIDEUR, longueur=150 - TENSION,
amortissement=0.5, couleur="#f59e0b")
tx, ty = sur_le_bras(-60, -11.5, TIR)
butoir = rectangle(x=tx, y=ty, largeur=30, hauteur=12, angle=TIR, fixe=True,
materiau="pierre", couleur="#334155")
if VERROU:
vx, vy = sur_le_bras(80, 11.5)
verrou = rectangle(x=vx, y=vy, largeur=30, hauteur=12, angle=ARME, fixe=True,
materiau="pierre", couleur="#ef4444")
# 5. le projectile, la cible
bx2, by2 = sur_le_bras(-152, -17)
bille = cercle(x=bx2, y=by2, rayon=12, materiau="bois", couleur="#ef4444")
for i in range(6):
rectangle(x=800 + i * 40, y=SOL_Y - 20 - 30, largeur=10, hauteur=60, materiau="bois", couleur="#e2e8f0")
rectangle(x=-700, y=SOL_Y - 20 - 20, largeur=20, hauteur=40, fixe=True, materiau="pierre")
rectangle(x=1100, y=SOL_Y - 20 - 20, largeur=20, hauteur=40, fixe=True, materiau="pierre")
camera.suivre(bille)
Construire ce script dans le laboratoireCe que le script fait, ligne par ligne
| Étape du tutoriel | En Python |
|---|---|
| 1. La base | sol(...), rectangle(..., fixe=True) |
| 2. Le bras | rectangle(angle=ARME) ; le fond de cuillère soudé par pivot(corps=[bras, fond], soude=True) |
| 3. Le pivot | pivot(x=PX, y=PY, corps=[bras, poteau]) — le bras est la première pièce : c'est lui qui tourne |
| 4. La propulsion | ressort(a=(bras, 90, 0), b=(qx, qy + 150), longueur=150 - TENSION) : un bout sur la queue du bras — (bras, 90, 0) est un point de la pièce, à 90 mm de son centre, donc à 50 mm de l'axe (accroché tout au bout de la queue, il tirerait trop fort) — l'autre au bâti ; la butée et le verrou sont des rectangles fixes placés par sur_le_bras() |
| 5. Le projectile | cercle(...) posé dans la cuillère par sur_le_bras(-152, -17) |
| 6. Les réglages | les constantes en tête : RAIDEUR, TENSION, ARME, TIR |
| 7. Le tir | à la main : effacer le verrou pendant la lecture. Ou VERROU = False : ça tire au Play |
Le point clé, invisible à la souris : le ressort est défini dans la pose de tir (sur_le_bras(90, 0, TIR)), pas dans la pose armée. Au tir il tire encore un peu (il plaque le bras sur sa butée) ; armé, il est étiré de 14 cm de plus — c'est cette tension qui claque.
Récupérer les objets, modifier les paramètres
Tout ce que le script crée est dans des variables (bras, bille, verrou…) — c'est ainsi qu'on « récupère » un objet en Python dans ce labo : il n'y a pas de noms ni de get_object. On les lit :
# (a coller SOUS le script de la catapulte)
print("le bras pese", round(bras.masse, 3), "kg, la bille", round(bille.masse, 3), "kg")
print("le bras fait", bras.largeur, "mm, incline de", bras.angle, "degres")
print("distance bille -> premier domino :", round(mecanique.distance(bille, (800, 250))), "mm")
Pour modifier la catapulte, on change les constantes et on ré-exécute (Ctrl+Entrée) : le script remplace la scène d'avant. RAIDEUR = 100 tire moins loin, TENSION = 60 plus loin, ARME = -30 arme plus bas.
Armer et déclencher
Le script arme la catapulte : il la construit tendue, retenue par le verrou. Il ne peut pas la déclencher : un script tourne avant la simulation, pas pendant (voir Ce qui n'existe pas (encore)). Trois façons de tirer :
- À la main : Play, clic sur le verrou, Suppr.
- Au Play :
VERROU = False. - Tout seul, à répétition : remplacer le verrou par une came — La catapulte à came.
Mesurer la distance du projectile
Pas de capteur en Python : la mesure se fait après coup. Play, tir, Pause quand la bille s'arrête, puis :
# Apres le tir, en pause : ou est la bille ?
for o in scene.trouver(type="cercle"):
print("bille en x =", round(o.x), "mm, soit", round((o.x + 349) / 1000, 2), "m depuis la cuillere")
Essayer ce code dans l’atelier Pythonscene.trouver() lit la scène à l'arrêt, avec les positions de la pause. Un script qui ne fait que lire ne change rien et ne laisse rien dans l'historique — tu peux le lancer autant de fois que tu veux.