Forsøk med en klassisk pendel blir brukt i veldig mange fysikk-kurs. Men skal man få teori og forsøk til å stemme, må man ta hensyn til luftmotstanden. I dette eksempelet viser vi hvordan du kan simulere og måle på en fysisk pendel, SAMTIDIG.
Kurs i modellering
Ønsker du kurs i modellering med Python for deg og dine kolleger?
Få inspirasjon og lær teknikkene for hordan du kan få det til på din skole.
Innholdsfortegnelse
Hvordan sette opp eksperimentet
Målingene er gjort ved å la en akselerasjonssensor være «kulen» i pendelen. Vi måler akselerasjon i snorens lengderetning og bruker målte verdier av denne til å sammenligne med den akselerasjonen vi forventer at «kula» utsettes for ved et gitt vinkelutslag.
Hva trenger du?
- En tynn og lett snor
- En trådløs akselerasjonsensor
- Et lodd som kan skrus fast under sensoren (vi brukte 4stk store skiver
- En liten maskinskrue og noen mindre skiver til å feste loddet
Valg vi gjorde (og anbefaler deg)
- Snorlengde ca. 2-2,4m. Med en lengre snor var det vanskelig å få stort nok pendelutslag og snorens lengde (og dermed vekt) skapte fort problemet.
- Loddet må være tyngre enn snora og skrus godt fast til sensoren.
- Vinkelutslaget bør være minst 20 grader, for å få tilstrekkelig forskjell i målt akselerasjon
Teorien bak simuleringene
En pendelbevegelse uten luftmotstand er relativt enkel matematisk og å simulere. Likningene for vinkel, vinkelhastighet og -akselerasjon er ganske like bevegelseslikningene, og kan programmers med f.eks. Eulers metode.
Likning 1: Bevegelseslikningene for sirkulær bevegelse.
Om luftmotstanden tas med, må man legge til et ekstra ledd i akselerasjonen:
Likning 2: Luftmotstand (kraft) og den avhengighet til luftens tetthet (rho), kulas tverrsnitt (A) og luftmotstandskoeffisienten (CD). Den siste blir stor hvis «kula» har en lite aerodynamisk form og må finnes ved prøving og feiling.
Likning 3: Akselerasjon i snorens lengderetning, beregnet for en gitt vinkel (theta) og hastighet v, hvor sistnevnte er regnet fra fra vinkelhastigheten.
Den numeriske integrasjonen av bevegelseslikningene kan gjøres relativt enkel og likner på vanlig Eulers metode for ds/dt = v og dv/dt = a.
Likning 4: «Kode-varianten» (den diskrete varianten) av Likning 1, med Eulers metode. NB Vinkelakselerasjonen er definert slik at den får negativt fortegn her.
Likning 5: Relasjonen mellom vinkelakselerasjon og -hastighet til sine «ordinære» størrelser akselerasjon og hastighet, hvor l er pendelens lengde.
Forklaring av kodens elementer
Simuleringen tar utgangspunkt i en oppgitt startverdi (utslag for pendelen) og regner selvkonsistent hvordan pendelen utvikler seg med tid.
Import av biblioteker
Til denne koden trenger vi et lite utvalg biblioteker. Om du vil prøve å kjøre denne på din PC, pass på at alle disse bibliotekene er installert.
import time
import numpy as np
from pasco import PASCOBLEDevice
import matplotlib.pyplot as plt
Sett verdi på variable
Forsøket settes opp ved hjelp av flere variable i begynnelsen av koden. Enhetens ID (PASCO-sensorens), snorens lengde, pendelens masse er de viktigste å sette til rett verdi for din pendel.
OBS Denne koden bruker animert plotting, dermed virker ikke Spyder. VSCode, Thonny, Mu, m.fl. er bekreftet å virke så lenge bibliotekene er lagt inn.
snor_lengde = 2.43 # Pendelens lengde
vinkel_grader = 25 # Maks utslag ved start
maks_perioder = 5 # Stopp simulering ved maks_perioder
device_id='469-773' # ID på din PASCO akselerasjon sensor
ymin = 8.0 # Laveste y-verdi i ditt akselerasjonsplot
ymax = 12.0 # Høyeste y-verdi i ditt akselerasjonsplot
xmax = 16.0 # Høyeste verdi for tid som plottes
#Konstanter til bruk i utregningene
pi = np.pi
g = 9.81 # Tyngdens akselerasjon
rho= 1.293 # Lufts tetthet
CD = 0.40 # Luftmotstand-koeffisient (en sfære har CD=0.45)
m = 0.050 # Kulas masse
r = 0.05 # Kulas radius
l = snor_lengde # Snorlengden
K = rho*pi*r*r*CD/2 # Brukes i likning F=K*v*v
Forberede plotvinduet
Denne koden bruker animert plotting, som alltid drar med seg litt hårete kode. Les dette om du er interessert i å lære hvordan dette virker, hvis ikke, blad videre.
#Gjør klar et interaktivt plottevindu
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(tid,aks_sim,lw=3,label="Simulering")
line2, = ax.plot(tid,aks_data,'-x',lw=3,label="PASCO data")
ax.set_xlim(0.,xmax)
ax.set_ylim(ymin,ymax)
ax.set_xlabel("Tid (s)")
ax.set_ylabel("Aks. ($m/s^2$)")
ax.legend()
fig.canvas.draw()
plt.pause(0.001)
Tidsintegrasjonen og lesing av data
Koble først til PASCO-sensoren. Her må du endre device_id til din sensor (se avsnittet om variable over).
# Gjør klar til måling av data
device = PASCOBLEDevice()
device.connect_by_id(device_id)
Den store jobben i denne koden, gjøres inne i while-løkken.
Først akselerasjonen som virker på loddet i pendelen. Disse inngår når vi skal finne vinkelakselerasjonen alpha.
Deretter leses akselerasjonen av med PASCO-sensoren i snorens lengderetning.
Så kommer det viktigste grepet. Vi vet i grunn ikke hvor lang tid koden bruker på å lese data og beregne alle størrelsene, samtidig vil vi at simuleringen skal være i sanntid og «på samme tidsakse» som måledataene. Normalt settes tidssteg-lengden dt i starten av koden, mens her beregnes den fra tidspunktene som leses av for hver iterasjon med time.time()-funksjonen til Python.
Deretter integreres bevegelseslikningene, slik at vi finner vinkel og vinkelhastighet i neste tidssteg. Metoden brukt her er enkleste variant: Eulers metode.
Siden vi ønsker å sammenligne akselerasjonen målt med sensoren med simulering, beregner vi teoretisk akselerasjon fra simulert vinkel (theta).
Så lagres nye data i en liste for plotting, og antall fullførte perioder telles.
while periode=0 and omega_start<0:
periode = periode + 1
print("Fullført periode",periode)
#Lagre data i lister
tid.append(tid_naa-tid_start)
aks_sim.append(aks)
#Oppdater linjesegmenter i plot
line1.set_xdata(tid)
line1.set_ydata(aks_sim)
line2.set_xdata(tid)
line2.set_ydata(aks_data)
fig.canvas.draw()
plt.pause(0.01)
#Forbered neste iterasjon
theta_start = theta_slutt
omega_start = omega_slutt
tid_forrige = tid_naa
Resultatet
Resultatet vi får er vist i videoen under. Etter å ha prøvd noen ganger, fant vi de rette verdiene for parameterne i koden, og grafen som produseres er mildt sagt imponerende
Vi ser at det er mulig å få en perfekt overenstemmelse mellom eksperiment og teori, hvor både periode, amplitude og demping som følge av luftmotstand blir likt.
Ønsker du kurs i hvordan sette opp dette eller liknende forsøk:
Kompetansemål
Det har vært en drøm for oss å utvikle, og ikke minst endelig få til, en slik kode hvor simulering og eksperiment kan gå i parallell. Og grunnen er nettopp disse:
DET ER GØY 🙂
… og fordi det huker av for MANGE kompetansemål samtidig. Her er de mest relevante:
Naturfag
- bruke enkle datasimuleringer eller animasjoner for å illustrere og forklare naturfaglige fenomener og teste hypoteser
- planlegge og gjennomføre ulike typer undersøkelser med identifisering av variabler, innhente og bearbeide data og skrive rapport med diskusjon av måleusikkerhet og vurdering av mulige feilkilder
Fysikk 2
- bruke numeriske metoder og programmering til å utforske og modellere fysiske fenomener
- utforske, beskrive og modellere bevegelse i to dimensjoner
Fysikk 1
- bruke numeriske metoder og programmering til å modellere og utforske bevegelse i situasjoner der akselerasjonen ikke er konstant
- planlegge og gjennomføre forsøk, analysere data og trekke konklusjoner – vurdere, bruke og lage modeller til å beskrive og forutsi fysiske fenomener
Andre
I tillegg er kan forsøket brukes til å huke av til flere kompetansemål i Matematikk og Teknologi- og Forskningslære.
Les eller last ned koden
Hele koden kan leses/lastes ned her (bruk «Copy»-knappen oppe til høyre i det grå feltet):
# Pendel m/luftmotstand - PYTHONSKOLE.NO
# Sanntid og simultan simulering og datalogging
# av en klassisk pendel
# 4.2.2022, kontakt@pythonskole.no
import time
import numpy as np
#from pylab import *
from pasco import PASCOBLEDevice
import matplotlib.pyplot as plt
snor_lengde = 2.43 # Pendelens lengde
vinkel_grader = 25 # Maks utslag ved start
maks_perioder = 5 # Stopp simulering ved maks_perioder
device_id='469-773' # ID på din PASCO akselerasjon sensor
ymin = 8.0 # Laveste y-verdi i ditt akselerasjonsplot
ymax = 12.0 # Høyeste y-verdi i ditt akselerasjonsplot
xmax = 16.0 # Høyeste verdi for tid som plottes
#Konstanter til bruk i utregningene
pi = np.pi
g = 9.81 # Tyngdens akselerasjon
rho= 1.293 # Lufts tetthet
CD = 0.40 # Luftmotstand-koeffisient (en sfære har CD=0.45)
m = 0.050 # Kulas masse
r = 0.05 # Kulas radius
l = snor_lengde # Snorlengden
K = rho*pi*r*r*CD/2 # Brukes i likning F=K*v*v
#Lister til å lagre data
omega = [] # Vinkelhastighet
theta = [] # Vinkelposisjon
aks_data = [] # Akselerasjon (data)
aks_sim = [] # Akselerasjon (simulering)
tid = [] # Tidssteg
#Setter initialverdier til løkka
tid_forrige = 0.0
periode = 0
omega_start = 0
theta_start = -pi*vinkel_grader/180
#Gjør klar et interaktivt plottevindu
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(tid,aks_sim,lw=3,label="Simulering")
line2, = ax.plot(tid,aks_data,'-x',lw=3,label="PASCO data")
ax.set_xlim(0.,xmax)
ax.set_ylim(ymin,ymax)
ax.set_xlabel("Tid (s)")
ax.set_ylabel("Aks. ($m/s^2$)")
ax.legend()
fig.canvas.draw()
plt.pause(0.001)
# Gjør klar til måling av data
device = PASCOBLEDevice()
device.connect_by_id(device_id)
# Alt er klart.
#Start pendelen først, og la brukeren velge når simuleringen starter
print("Simuleringen er klar!")
print("Vent til pendelen er på maks utslag,")
input("trykk Enter for å starte...")
#Start simulering og måling
tid_start = time.time()
tid_forrige = tid_start
#Ferdig med å måle data (koble fra sensor)
device.disconnect()
#Beregn avvik mellom datapunkter i simulert og eksperimentell data
diffsum = 0.0
count = 0.0
for i in range(len(aks_data)):
if (not aks_data[i] == None) and (not aks_sim[i] == None):
count = count + 1
diffsum = diffsum + np.absolute(aks_data[i]-aks_sim[i])
error_abs = round(diffsum/len(aks_data),2)
error_rel = round(diffsum/count/g,2)
print("Gjennomsnittlig absolutt feil:", error_abs)
print("Gjennomsnittlig relativ feil :", 100.0*error_rel,"%")
#Lukk interaktivt plottevindu for å få frem et statisk/endelig plot
input("Animasjon ferdig. Lukk plot-vinduet og trykk enter for å fortsette...")
plt.ioff()
plt.plot(tid,aks_sim,label="Simulering")
plt.plot(tid,aks_data,'-x',label="PASCO-data")
plt.title("Klassisk pendel - Akselerasjon")
plt.legend()
plt.xlabel("Tid (s)")
plt.ylabel("Aks. ($m/s^2$)")
plt.show()