← Område 2 Guide · Linjeföljaren Felsökning

Teknik 1 · område 2 · pass 7

Linjeföljaren

Fem tal säger var linjen är. Biblioteket gör om dem till ett enda – en position – och på den kan roboten styra. Först måste den veta vad som är vitt och vad som är svart: det är kalibreringen. Sidan förutsätter att biblioteken ligger på Pico:n.

1. Kalibrera

Vitt golv ger 60 i ett rum och 200 i ett annat. Sensorerna är inte heller exakt lika. Därför kalibrerar du: låt varje sensor se både vitt och svart, så vet biblioteket vad som är vad.

from TRSensor import TRSensor
from time import sleep

sensor = TRSensor()

for i in range(100):
    sensor.calibrate()

while True:
    position, varden = sensor.readLine()
    print(position)
    sleep(0.2)
Vagga roboten medan kalibreringen kör

De 100 varven tar tre–fyra sekunder. Under tiden håller du roboten i handen och vaggar den fram och tillbaka i sidled över tejpen, så att alla fem sensorerna hinner se både vitt och svart. Kalibreringen görs om varje gång programmet startar – vagga direkt när du kört.

2. En position

readLine() svarar med två saker på samma gång – returvärdet från förra veckan, fast två i stället för ett:

NamnVad det är
positionEtt tal 0–4000. 0 = linjen under vänster kant. 2000 = linjen i mitten. 4000 = under höger kant. Ser ingen sensor linjen får du 0 eller 4000, beroende på vilken sida den senast var på
vardenListan igen, men kalibrerad: 0 = det ljusaste sensorn såg, 1000 = det mörkaste. Summan av alla fem säger hur mycket svart roboten ser totalt – alla över tejp ger nära 5000

Flytta roboten i sidled över linjen och se position glida. Visa den stort på skärmen: lcd.text("pos " + str(position), 10, 10, lcd.VIT).

3. kor(v, h) – två farter

För att svänga mjukt behöver hjulen olika fart. En funktion som tar två – den var utmaning förra veckan, nu behöver alla den. Pinnarna från kor.py ovanför.

def kor(v, h):
    v_fram.value(1)
    v_bak.value(0)
    h_fram.value(1)
    h_bak.value(0)
    fart_v.duty_u16(int(v * 65535 / 100))
    fart_h.duty_u16(int(h * 65535 / 100))

kor(20, 45): vänster hjul långsamt, höger fort – roboten svänger vänster. kor(40, 40): rakt.

4. Följa linjen: bang-bang

Tre lägen, inget däremellan. Antingen eller – det heter bang-bang.

while True:
    position, varden = sensor.readLine()
    if position < 1500:
        kor(20, 45)
    elif position > 2500:
        kor(45, 20)
    else:
        kor(40, 40)

Linjen till vänster (under 1500) → sväng vänster. Till höger (över 2500) → sväng höger. Mitten → rakt. Ställ roboten på ovalen, vagga för kalibreringen, släpp. Den följer – och vaggar. Justera farterna tills den klarar ett varv.

Svänger den fel håll?

Då är sensorkortet vänt, så att 0 är höger kant. Byt < och > – eller byt farterna i de två svängarna. Testa först med print(position): linjen till vänster ska ge under 2000.

5. Följa linjen bättre: P-reglering

Bang-bang svänger lika hårt oavsett om linjen är lite eller mycket åt sidan. Bättre: ju längre ut linjen är, desto mer sväng. Det heter proportionell reglering, P-reglering, och det är en rad:

fart = 45
k = 0.015

while True:
    position, varden = sensor.readLine()
    fel = position - 2000
    v = fart + fel * k
    h = fart - fel * k
    kor(max(0, min(100, v)), max(0, min(100, h)))
RadenVad den gör
fel = position - 2000Hur långt från mitten linjen är: −2000 … 2000. Noll = mitt på
v = fart + fel * kLinjen till höger (fel positivt) → vänster hjul fortare → roboten svänger höger. Lagom mycket
kHur hårt roboten reagerar. För litet: tappar kurvan. För stort: vaggar. Hitta ert k – börja på 0.015
max(0, min(100, v))Håller farten inom 0–100. Utan det kan v bli 75 eller −5, och duty_u16 vill inte ha det

Det är hela reglertekniken i en rad. Att ni provade bang-bang först och bytte till P – och varför – är precis den sortens resonemang dokumentationen frågar efter.

6. main.py

Kalibreringen först, sedan tre sekunder, sedan loopen. Ladda upp, dra ur kabeln, ställ på ovalen, slå på, vagga direkt, släpp.

# pinnar, kor() och stopp() ovanför ...

sensor = TRSensor()
lcd = ST7789()

for i in range(100):
    sensor.calibrate()
sleep(3)

while True:
    position, varden = sensor.readLine()
    lcd.fill(lcd.SVART)
    lcd.text("pos " + str(position), 10, 10, lcd.VIT)
    lcd.show()
    if position < 1500:
        kor(20, 45)
    elif position > 2500:
        kor(45, 20)
    else:
        kor(40, 40)

Skärmen visar positionen medan den kör. Det är så du ser vad roboten ser när den tappar linjen.

Klart när — det här ska alla ha

Om du hinner — utmaning

Kryssen sparas i din webbläsare.

7. Felsökning

7 rader

SymptomTrolig orsakÅtgärd
position är alltid 0 eller 4000Ingen kalibrering, eller kalibrerad utan att någon sensor såg tejpenKör om programmet och vagga över linjen under de 100 varven
Roboten svänger åt fel hållSensorkortet vänt, eller </> förväxladeTesta med print: linjen till vänster ska ge under 2000. Annars byt tecknen
Tappar linjen i kurvanFör hög fart, eller för liten skillnad mellan hjulenMittfart 30. Svängarna 15/45
Vaggar våldsamtBang-bang gör det. Eller för stort kMindre skillnad mellan farterna, eller P-reglering med mindre k
Kör rakt fram och struntar i linjenKalibreringen gjordes i luften – allt ser likadant utRoboten ska stå på banan under kalibreringen
Ingenting händer efter calibrate-loopenDen tar 3–4 sekunderVänta. Skriv något på skärmen efter loopen så att du ser när den är klar
ValueError på duty_u16Farten är utanför 0–100max(0, min(100, …)) runt v och h

Ord på den här sidan

OrdBetyder
kalibreringLåta sensorn se vitt och svart så att den vet vad som är vad. Görs varje start
positionEtt tal 0–4000 som säger var linjen är under roboten. 2000 = mitten
bang-bangStyrning med bara några fasta lägen. Sväng eller sväng inte
P-regleringStyrning där reaktionen är proportionell mot felet. Lite fel – lite sväng
felSkillnaden mellan där man är och där man vill vara
kFörstärkningen – hur hårt man reagerar på felet

Ordträning