Jalgpallirobot

Taust

Järgnev õpetus on koostatud TTÜ avatud ülikooli ja MTÜ TTÜ Robotiklubi koostöös eesmärgiga aidata Robotexil osalevaid või seda plaanivaid võistkondi.

Robotex on eesti suurim ja populaarseim võistlus, mis leiab aset igal aastal novembris või detsembris Tallinnas. Võistlusel on ette antud lähteülesanne, mis tavaliselt muutub igal aastal. Täpsemat infot võistluse ja reeglite kohta saab aadressilt http://www.robotex.ee

Käesolev juhend sisaldab täielikku dokumentatsiooni ja praktilisi näpunäiteid ühe Robotex 2010 reeglitele vastava roboti ehitamiseks. Robot on oma ülesehituselt ja võimetelt ette nähtud juuniorite klassis osalemiseks, kus robotitel pole kasutada kalleid ja kiireid mootoreid, pisikesi arvuteid ning kaameraid. Sellesse klassi on oodatud gümnaasiumiõpilased ja robootikaga alles tutvust tegevad huvilised.

Juhendi baasil loodud platvormi eesmärgiks on olla lihtne ning odav esimene katsetus robotite ehitamise vallas. Sellest lähtuvalt kasutatakse laialt saadaolevaid konstruktsioonimaterjale ning elektroonikakomponente. Roboti baaskomponentideks on valitud Kodulabori komplektis sisalduvad moodulid. Kuna kõiki komponente kodulaborites siiski ei leidu, lisanduvad mõningad spetsiifilised osad. Tänu moodularhitektuurile võib iga soovija robotit muuta vastavalt oma äranägemisele.

Kontseptsioon

Kuna ilma pilditöötluseta ja kallite laserkaugumõõdikuteta on pallide leidmine väljakult tehniliselt üsna keerukas, tuleb minna lihtsama vastupanu teed ja kaugelt avastamise asemel palle aktiivselt ringi sõites otsida. Selleks on roboti algoritmis ette nähtud väljakul edasi-tagasi sõitmine ja pallide juhuslik avastamine.

Liikumine väljakul

Robot kasutab pallide leidmiseks ultraheli kaugusandurit. Andur on asetatud mõõtma kaugust roboti parema külje peale. Pallide otsimiseks sõidab robot väljaku keskel ühe värava juures teise juurde ja mõõdab pidevalt temast paremale jäävate objektide kaugust. Kui roboti ja seina vahele jääb pall siis kauguse näit väheneb ja robot võtab hoo maha, et vaikselt liikudes pallist mööduda nii, et kaugusanduri näit jälle suureneks. Sedasi saab robot üpris täpselt palli kõrvale sõita.

Palli otsimine paremale suunatud ultrahelianduri abil

Edasi on põhimõtteliselt lihtne - robotil tuleks keerata 90 kraadi paremale ja sõita pallini, kuid paraku ei ole palli kõrvale seisma jäämine ja pööre nii täpne, et robot saaks kätte poole meetri kaugusel oleva palli. Selleks on pärast palli avastamist kaks varianti: kohe palli püüdma minek või selle lähemalt otsimine. Kui pall asub robotist kuni 30 cm kaugusel pöörab robot kohe palli poole ja üritab selle kätte saada nii nagu on näidatud ka järgneval skeemil:

Lähedal seisnud palli püüdmine

Kui pall asub kaugemal kui 30 cm siis robot sõidab esmalt edasi veel 10 cm, siis pöördub 90 kraadi paremale ja hakkab otse seina suunas sõites ultrahelianduriga otsima palli mis peaks robotist taaskord paremat kätt olema. Nii kui ultraheliandur näeb lähedal olevat objekti, sõidab robot natuke edasi, pöördub teist korda 90 kraadi paremale ja saab palli üsna nina alt kätte. Seda kauge palli leidmise algoritmi iseloomustab järgnev skeem:

Kaugel seisnud palli püüdmine

Robot saab pallianduri abil aru kas ta on palli kätte saanud või mitte. Palli püüdmiseks on roboti ninas V-kujuline lehter ja selle kohal pöörlev kummist rull mis paneb lehtrisse sattunud palli pöörlema roboti suunas. Palli pööritamine takistab selle minema veeremist roboti liikumise ajal.

Pärast palli kättesaamist hakkab robot otsima vastase väravat kuhu pall toimetada. Värava leidmiseks on väravate kohal infrapuna (IR) majakad mis kiirgavad väljaku suunas RC5 protokolliga signaale, ehk põhimõtteliselt on saatjad justkui telekapuldid. Värava leidmiseks on robotil kahe kanaliga RC5 vastuvõtja millel on kahe infrapuna detektori vahel sein. Kui vastuvõtja on suunatud majaka suunas, kiirgab majakas mõlemasse detektorisse; kui vastuvõtja on majaka suhtes viltu, siis signaal jõuab ainult ühte detektorisse. Vastavalt sellele milline detektor majakat “näeb” saab robot aru värava suunast. Kui suund on õige saab robot otse värava suunas sõita.

Värava suuna leidmine RC5 vastuvõtja abil

Roboti ees on ~8 cm kõrgusel infrapuna kaugusandur, mis mõõdab takistuste kaugust. Takistuseks võivad võistlusel olla vastase robot või seinad. Sellesama anduriga saab robot ka aru väravast kuna väravate tagumise seina alumises 10 cm osas on riie millelt infrapuna kiirgus peegeldub. Sõites värava suunas ja jõudes värava seinast ~20 cm kaugusele lõpetatakse palli kinnihoidmine ja lükatakse see väravasse. On oht, et värava suunas sõites võib robot värava seina asemel märgata vastast - selleks ootab robot enne palli lahti laskmist natukese, lootuses, et vastane liigub eest ära.

Takistustest hoidumine ja värava leidmine infrapuna kaugusanduri abil

Löögimehhanism pallide kaugel väravasse löömiseks puudub, kuna see on tehniliselt keerukas ja otseselt pole seda vaja. Pärast palli vastase väravasse lükkamist hakkab robot palle otsima oma värava suunas liikudes.

Dokumentatsioon

Komponentide nimekiri

Komponent Selgitus Kogus
Veermik 1
Alusplaat Alumiiniumist kere 1
Haarats Alumiiniumist raam rulli ja pallianduri jaoks 1
Mootor DC 1
Rull Palli keerutamiseks 1
Kummirõngas Palli keerutamiseks 2
Kodulabori Kontrollermoodul Mikrokontrolleriga põhiplaat 1
Kodulabori Mootorite moodul H-sillad mootorite juhtimiseks 1
Kodulabori Andurite moodul Erinevate andurite ühendamiseks 1
Kodulabori Kommunikatsioonimoodul RC5 vastuvõtjaga suhtlemiseks 1
Ultraheli kaugusandur Palli leidmiseks 1
Infrapuna kaugusandur Takistuste avastamiseks 1
Kooder Optokatkesti sammude lugemiseks 2
Palliandur Peegeldusandur palli nägemiseks 1
M3x6 polt Komponentide kinnitamiseks 16
M3x10 polt Koodrite kinnitamiseks 4
Mutter Komponentide kinnitamiseks 20
Seib Komponentide kinnitamiseks 4

Konstruktsioon

Jalgpalliroboti osad

Jalgpalliroboti keskseks osaks on Pololu RP5 lintidega veermik sellele kinnitatava alusplaadiga. Alusplaadi külge kinnitatakse omakorda rullimehhanism, elektroonikamoodulid, andurid, koodrid, jms. Jalgpalliroboti konstruktsiooni väljatöötamisel on lähtutud sellest, et robot oleks võimalikult kompaktne, lihtne ja käepäraste vahenditega ehitatav. Materjalide ja erinevate detailide valikul on arvestatud nende kättesaadavusega.

Veermik

Pololu RP5 veermik

Alusplatvormina kasutatakse Pololu RP5 lintidega veermikku. Veermikuga on kaasas kaks alalisvoolumootorit, kummagi lindi jaoks üks. Nende abil suudab veermik liikuda kiirusega kuni 15 cm/s. Lindid tagavad platvormile hea manööverdamisvõime. Lisaks on platvormiga kaasas ka patareihoidik 6 AA suuruses patarei jaoks. Platvormi mõõtmed on 180 mm x 140 mm x 60 mm. Augud alusplaadi kinnitamiseks on platvormil algselt juba olemas, kuid need tuleb siiski veel keermestada. Rohkem informatsiooni veermiku ja selle tellimise kohta saab järgnevalt aadressilt: http://www.pololu.com/catalog/product/1060

Alusplaat

Alusplaat

Alusplaat seob omavahel jalgpalliroboti kõiki detaile. Erinevate komponentide kinnitamiseks on alusplaadile puuritud vajalikud augud. Kõik komponendid on seejuures kinnitatud M3 polte ja mutreid kasutades. Alusplaat ise kinnitatakse veermiku külge nelja poldi abil. Lisaks poldiaukudele on alusplaadil auk patareihoidiku lihtsamaks väljavõtmiseks ning kaks auku koodrite kaablite jaoks. Alusplaadile tuleb teha ka kaks painutust (vt pilti). Alusplaadi materjali valikul tuleb arvestada sellega, et materjali oleks võimalik painutada.

Rullimehhanism

Rullimehhanism

Rullimehhanism koosneb haaratsist, rullist, rulli kummirõngastest, rulli käitavast alalisvoolumootorist ja hingest, mille abil mehhanism alusplaadi külge kinnitatakse. Haaratsile kinnitatakse ka kahepoolse teibiga optiline andur. Alalisvoolumootorina kasutatakse Kodulabori Micro motors L149.6.10 reduktoriga mootorit.

Haarats
Haarats

Haarats seob omavahel rullimehhanismi kõiki komponente. Haaratsi külge kinnitatakse alalisvoolumootor, optiline andur ning hing. Lisaks sellele on haaratsi üheks põhiülesandeks golfipalli fikseerimine rulli ette. Haarats on konstrueeritud nii, et golfipalli sattumisel haaratsi ette suunatakse see rulli pindade poole. Haaratsi antud ehitus takistab ka golfipalli minema veeremist roboti pööramisel. Kuna haaratsile tuleb teha mitmeid painutusi, peab materjali valikul sellega arvestama.

Rull
Rull ja kummirõngad

Rulli tööpõhimõte seisneb palli sellisel viisil pöörlema panemises, et see kogu aeg roboti poole veereks . Rulli diameeter on 20 mm ja laius 50 mm. Rulli ühte otsa on puuritud auk mootori võlli jaoks ning sellega risti on puuritud ja keermestatud teine auk, mille kaudu poldi abil rull võlli külge fikseeritakse.

Kummirõngad

Rullile kinnitatakse kaks kummirõngad siseläbimõõduga 19 mm ja välisläbimõõduga 30 mm, kummide laius on 15 mm. Kummidevaheline kaugus rullil on 10 mm. Kummid tagavad parema kontakti rulli ja golfipalli vahel ja seega golfipalli parema püsimise rulli ees.

Andurite kinnitus

IR andur, RC5 vastuvõtja kinnitusega

Infrapuna kaugusanduri ning RC5 vastuvõtja kinnitamiseks on lihtne U-kujulise profiiliga kinnitus. Kinnitusele on puuritud augud infrapuna kaugusanduri ja kinnituse enda alusplaadi külge kinnitamiseks. RC5 vastuvõtja fikseerimiseks kasutatakse kahepoolset teipi. Kuna tehakse painutusi, peab sellega ka kinnituse materjali valikul.

Kodulabori moodulid

Kodulabori moodulid puksidel

Patareihoidiku väljavõtmise võimaldamiseks on Kodulabori moodulid paigaldatud alusplaadile puksidega. Alusplaadil on moodulite kinnitamiseks puuritud vastavad augud. Moodulid paiknevad kihiliselt ning on omavahel kergesti ühendatavad.

Elekter

Kodulabori moodulid

Roboti ehitamiseks kasutatakse Kodulabori täiskomplekti, mis sisaldab järgnevaid mooduleid (eraldi plaate):

  • AVR ATmega128 arendusplaat (kontroller)
  • Kasutajaliides ehk sisend-väljundmoodul (nupud, valgusdioodid, 2 x LCD väljund, 7-segment-indikaator)
  • Mootorite moodul
  • Andurite moodul

Moodulite pikema kirjelduse koos pistikute piikide täpse kirjeldusega leiab leheküljelt

http://home.roboticlab.eu/et/hardware/homelab

Järgneval pildil on toodud lihtsustatud ülevaade andurite jms ühendamisest.

Toiteahel

Robotil vajab toitepinget nii kontrolleri moodul kui ka mootorite moodul. Mõlemad kasutavad energiaallikana sama akupatareid. Kasutatakse kaheks hargnevat juhet. MOotorite mooduli toitepistiku ühendamise õpetus on lehel

http://home.roboticlab.eu/et/hardware/homelab/motor

NB! Standardse akupatarei fikseeritud pinge tõttu peab kontrolleri plaadil lühistama dioodsilla. Silla funktsioon plaadil on pöörata toitepinge polaarsus alati ühte pidi. See tähendab, et silda kasutades pole toitepinge polaarsus tähtis. Paraku jääb sillal u 1,5V pingelangu, mis on lubamatult palju.

Lühistades silla on toitepinge õige polaarsus tähtis! Pistiku keskmine piik on positiivne ja välime äär negatiivne.

Koodrid

Optokatkesti

Roboti veermikul on mõlema lindi ülekandes 2 aukudega hammasratast. Asetades optokatkesti niimoodi hammasratta kohale, et see jääb optokatkesti pilu vahele saab optokatkestiga registreerida hammasrattas olevaid auke. Kui optokatkesti vahele jääb auk, siis optokatkesti ühes otsas oleva valgusdioodi valgus kiirgab teises otsas oleva fototransistori peale ja viimane hakkab voolu juhtima. Lugedes pöörlevas hammasrattas olevaid auke saab selle info põhjal välja arvutada läbi teepikkuse. Originaalis on mõlemas veermiku hammasrattas üks auk, kuid sinna tuleb sümmeetriliselt juurde puurida 2 auku, et koodri täpsust parandada. Sedasi saab lindi läbitud teepikkust mõõta ligikaudu 1 cm täpsusega.

Koodrid on ühendatud Kodulabori Mootorite mooduli “encoder” pistikupesas. Vasaku poole kooder on ülemises, parema poole kooder alumises pesas. Koodrite impulside lugemiseks kasutatakse tarkvara Kodulabori teegi koodrite moodulit.

RC5 vastuvõtja

RC5 vastuvõtja

Robotexil on väravate kohale paigutatud infrapuna signaali saatjad, mis edastavad Philips’i RC5 protokolli abil kanaleid 1 kuni 4. Nende signaalide vastuvõtmiseks on tehtud eraldiseisev moodul. Vastuvõtumoodul ühendatakse kodulabori kommunikatsioonimooduliga kaabliga, mille ühendusskeem on välja toodud plokkskeemis. Samas on välja toodud info vastuvõtja olulisemate komponentide kohta.

Vastuvõtumoodulile on paigutatud kaks signaali vastuvõtjat/demoduleerijat. Tänu sellele on võimalik paika panna roboti asend väravate suhtes.

Vastuvõtja saadab 4800 bps kiirusel välja 1-baidiseid UART sõnumeid, milles sisaldub infrapunavastuvõtja indeks ning vastuvõetud kanal. Väljasaadetavate UART sõnumite kirjeldused on välja toodud allpool olevates tabelites:

Vastuvõtja indeksiga 0 (vasakpoolne)

RC5 vastuvõtja plokkskeem
Kanal Kaheksandiksüsteemis(HEX) Kahendsüsteemis(BIN)
1 0x01 0b00000001
2 0x02 0b00000010
3 0x03 0b00000011
4 0x04 0b00000100

Vastuvõtja indeksiga 1 (parempoolne)

Kanal Kaheksandiksüsteemis(HEX) Kahendsüsteemis(BIN)
1 0x11 0b00010001
2 0x12 0b00010010
3 0x13 0b00010011
4 0x14 0b00010100

RC5 vastuvõtja skeemi ja trükkplaadi pildid. Skeemi ja trükplaadi failid, tarkvara ning komponentide nimistu paiknevad lehekülje alumises osas, alajaotuses “Failid”.

RC5 vastuvõtja skeem
RC5 vastuvõtja trükkplaat

Palliandur

Palli tuvastamiseks rulliku all kasutatakse infrapuna peegeldusandurit. Saatajalt peegeldunud kiirgus jõuab vastuvõtjasse ja selle kiirguse intensiivsuse järgi saab määrata objekti kauguse. Intensiivsus sõltub lisaks kaugusele ka objekti pinna värvist ja siledusest. Robotexi ülesande golfipall on alati ühesugune ja seega vastab igale intensiivuse tasemele kindel kaugus andurist.

Pallianduri skeem

Kuna võistlusel on alati palju välklampe, kaameraid, valgusteid jms infrapunakiirguse allikaid, siis kasutatakse moduleeritud signaali, st saatja kiirgab teatud sagedusel ja vastuvõtja reageerib ainult sellel sagedusel olevale signaalile. Kõik selle teeb ära üks integraallülitus - Hamamatsu S4282-51. Ainsaks väliseks komponendiks on infrapunakiirgur (diood) ning tundlikkust reguleeriv takisti jadamisi dioodiga.

Pallianduri skeem on näidatud pildil. U1 on Hamamatsu S4282-51 andur. Kondensaator C1 silub toitepinge kõikumist. Kuna IP-diood võtab üsna palju voolu, siis selle sisse-välja lülitamise hetketel muutub voolutugevus anduri juhtmetes. Juhtmete induktiivsuse tõttu ei saa muutus toimuda hetkeliselt ja kondensaator täidab lühiajalise energiaallika osa. Kondensaatori parameetrid pole kriitilised. Peaasi, et nimipinge ületab 5V ja mahtuvus 1uF või rohkem.

Takisti R1 määrab anduri tundlikkuse. Ilma takistita oleks anduri reageermiskaugus u 5cm (sõltub ka IP-dioodi valikust). Takisti valimine käib katse-eksituse meetodil (vahemik 0 - 30 oomi).

Peegeldusandur

Dioodi valimisel tuleb lähtuda S4282-51 andmelehel märgitud lainepikkusest (800nm), kus andur on kõige tundlikum. Dioodi kiirgusnurk peaks olema võimalikult väike, et palliandur näeks ainult otse ette. Suure nurgaga dioodi puhul võib andur reageerida juba siis, kui pall pole täpselt otse anduri ees. Dioodi kiirgusnurk 11 kraadi ja alla selle tagab hea tulemuse.

Pistik JP1:

  1. Signaal, madal kui andur tuvastab palli
  2. Toide +5V
  3. Maa (0V)

Programm

Roboti tarkvara on kirjutatud AVR Studios C keeles. Tarkvara kasutab kodulabori teeki ja AVR-GCC kompilaatorit mis tuleb kaasa WinAVR-iga. Programm on jagatud funktsioonide järgi mitmeks failiks - näiteks on sõitmise funktsioonide ja andurite näitude lugemiseks erinevad failid. Põhifailis asub main funktsioon mis käivitab kõik juhtimis- ja tagasiside protsessid. Roboti algoritm asub samas failis olevas suures olekutabelis.

Programm on üles ehitatud tavapärase olekumasina eeskujul, kuid et kood liiga pikaks ei läheks ning kogu algoritm ühes kohas koos oleks, kasutatakse sisendite kontrolliks ja väljundite juhtimiseks ühtset suurt tabelit. Selleks, et algoritmis saaks kiirelt ja mugavalt lugeda andurite näite, juhtida mootoreid ja kuvada infot, on kõik muud protsessid toimima pandud katkestuste pealt. Katkestuste pealt töötades ei sega mõõtmis- ja juhtimisprotsessid algoritmi tööd ja vastupidi - need toimuvad paralleelselt.

Tabeli struktuur on järgmine:

  • Sisendid
    • Olek
    • Taimer
    • Vasak enkooder
    • Parem enkooder
    • Nupud
    • Infrapuna kaugusandur
    • Ultraheli kaugusandur
    • Palliandur
    • Oma värava suund
    • Vastase värava suund
  • Väljundid
    • Uus olek
    • Taimer
    • Platvorm
    • Pallihoidmise rullik
    • 7-segmendiline indikaator
    • Punane LED
    • Ultraheli kaugusanduri väärtuse meelde jätmise lipuke

Tabeli ridade pikkuse vähendamiseks ning määramata sisendite/väljundite võimaldamiseks kasutatakse tabelis makrokäsklusi. Järgnevalt on kasutatavad käsklused lahti seletatud.

Käsklus Seletus
EQ(n) Sisend peab olema n-ga võrdne
NE(n) Sisend ei tohi olla n-ga võrdne
GT(n) Sisend peab olema suurem n-st
LT(n) Sisend peab olema väiksem n-st
BM(n) Kontrollitakse n-ndat bitti sisendis
CSM(n) Sisendi väärtus peab olema suurem või võrdne n ja eelmise meelde jäetud ultraheliandurist saadud kauguse summaga
CSB(n) Sisendi väärtus peab olema suurem või võrdne n ja eelmise meelde jäetud ultraheliandurist saadud kauguse vahega
DRV(l, r) Seab vasaku mootori kiiruseks l ja parema mootori kiiruseks r. Arvud -100…100, kus 0 on peatatud olek ning negatiivne arv tähistab sama kiirust vastassuunas.
STA(n) Seab uue oleku n
TMR(n) Seab taimeri uueks väärtuseks n
ROL(0/1) Lülitab pallihoidmise rulliku välja/sisse
LED(0/1) Lülitab LED'i välja/sisse
SEG(0-9) Seab 7-segmendilise indikaatori näidatava väärtuse 0-9
//
// Input-output logic list
// This table does all the "thinking"
// 
logic_step logic_list[] =
{
//    INPUT                                                                                         OUTPUT
//    STATE     TIMER          CODEL          CODER  BUTTN     IRRED     USONI  BALLS    OWN   OPPO     STATE      TIMER        CHASSIS  ROLLER  SEGMNT  LEDRED  US M+
  { EQ(  1),        0,             0,             0, BM(1),        0,        0,     0,     0,     0, STA(  2),         0,              0,      0,      0, LED(1),    0 },  // Start command
  {       0,        0,             0,             0, BM(4),        0,        0,     0,     0,     0, STA(  1),         0, DRV(   0,   0), ROL(0), SEG(0), LED(0),    0 },  // Stop command
  // --- Drive to the center ------------------------------------------------------------------------------------------------------------------------------------------
  { EQ(  2),        0,             0,             0,     0,        0,        0,     0,     0,     0, STA(  3),         0, DRV(-100, 100),      0,      0,      0, true },
  { EQ(  3),        0,             0,        GT(18),     0,        0,        0,     0,     0,     0, STA(  4),         0, DRV( 100, 100),      0,      0,      0,    0 },  
  { EQ(  4),        0,     CSB(1000),     CSB(1000),     0,        0,        0,     0,     0,     0, STA(  5),         0, DRV( 100,-100),      0,      0,      0,    0 },
  { EQ(  5),        0,        GT(18),             0,     0,        0,        0,     0,     0,     0, STA( 10),         0, DRV(   0,   0),      0,      0,      0,    0 },
  // --- Start searching ----------------------------------------------------------------------------------------------------------------------------------------------
  { EQ( 10),        0,             0,             0,     0,        0,        0,     0,     0,     0, STA( 11),         0, DRV( 100, 100), ROL(0), SEG(1),      0,    0 },
  { EQ( 11),        0,             0,             0,     0,        0,        0, EQ(1),     0,     0, STA( 90),         0,              0,      0,      0,      0,    0 },  // Found a random ball
  { EQ( 11),        0,             0,             0,     0,        0, LT( 600),     0,     0,     0, STA( 20),         0, DRV(   0,   0),      0,      0,      0,    0 },  // Sudden closer distance on the right, investigate
  { EQ( 11),        0,             0,             0,     0, LT( 200),        0,     0,     0,     0, STA(100),         0, DRV(   0,   0),      0,      0,      0,    0 },  // Something's in the way, turn around
  // --- Precise search -----------------------------------------------------------------------------------------------------------------------------------------------
  { EQ( 20),        0,             0,             0,     0,        0,        0,     0,     0,     0, STA( 21), TMR(5000), DRV(  50,  50),      0, SEG(2),      0,    0 },
  { EQ( 21),        0,             0,             0,     0,        0,        0, EQ(1),     0,     0, STA( 90),         0,              0,      0,      0,      0,    0 },  // Found a random ball
  { EQ( 21),        0,             0,             0,     0, LT( 200),        0,     0,     0,     0, STA(100),         0, DRV(   0,   0),      0,      0,      0,    0 },  // Something's in the way, turn around
  { EQ( 21), EQ(   0),             0,             0,     0,        0, LT( 600),     0,     0,     0, STA( 22),         0, DRV(   0,   0),      0,      0,      0,    0 },  // Suspected ball seems to be a wall instead
  { EQ( 21), EQ(   0),             0,             0,     0,        0, GT( 599),     0,     0,     0, STA( 10),         0,              0,      0,      0,      0,    0 },  // Didn't recognize a ball, return to search
  { EQ( 21), LT(4500),             0,             0,     0,        0, GT( 599),     0,     0,     0, STA( 30),         0, DRV(   0,   0),      0,      0,      0, true },  // Identified a ball, go get it 
  { EQ( 22),        0,             0,             0,     0,        0,        0,     0,     0,     0, STA( 23),         0, DRV(-100, 100),      0,      0,      0, true },  // Try to get away from the wall
  { EQ( 23),        0,             0,        GT(18),     0,        0,        0,     0,     0,     0, STA( 24),         0, DRV( 100, 100),      0,      0,      0,    0 },
  { EQ( 24),        0,      CSB(750),      CSB(750),     0,        0,        0,     0,     0,     0, STA( 25),         0, DRV( 100,-100),      0,      0,      0,    0 },
  { EQ( 25),        0,        GT(18),             0,     0,        0,        0,     0,     0,     0, STA( 10),         0, DRV(   0,   0),      0,      0,      0,    0 },  // Resume search
  // --- Turn to ball -------------------------------------------------------------------------------------------------------------------------------------------------
  { EQ( 30),        0,             0,             0,     0,        0,        0,     0,     0,     0, STA( 31),         0, DRV( 100, 100), ROL(1), SEG(3),      0,    0 },
  { EQ( 31),        0,             0,             0,     0,        0,        0, EQ(1),     0,     0, STA( 90),         0,              0,      0,      0,      0,    0 },  // Found a random ball
  { EQ( 31),        0,  GT(MTS(150)),  GT(MTS(150)),     0,        0,        0,     0,     0,     0, STA( 32),         0, DRV( 100,-100),      0,      0,      0,    0 },  // Turn right
  { EQ( 32),        0,        GT(18),             0,     0,        0,        0,     0,     0,     0, STA( 33),         0, DRV(  75,  75),      0,      0,      0,    0 },  // Start driving towards the wall
  { EQ( 33),        0,             0,             0,     0, LT( 150),        0,     0,     0,     0, STA( 40),         0, DRV(-100, 100), ROL(0),      0,      0,    0 },  // Wall too close, turn around and get back to the center
  { EQ( 33),        0,             0,             0,     0,        0, LT( 300),     0,     0,     0, STA( 34),         0, DRV( 100, 100),      0,      0,      0, true },  // Spotted the ball
  { EQ( 34),        0,  GT(MTS( 50)),  GT(MTS( 50)),     0,        0,        0,     0,     0,     0, STA( 35),         0, DRV( 100,-100),      0,      0,      0,    0 },  // Turn towards the ball
  { EQ( 35),        0,        GT(18),             0,     0,        0,        0,     0,     0,     0, STA( 36),         0, DRV(  90,  90),      0,      0,      0,    0 },
  { EQ( 36),        0,       CSM(50),       CSM(50),     0,        0,        0, EQ(1),     0,     0, STA( 90),         0,              0,      0,      0,      0,    0 },  // Caught the ball
  { EQ( 36),        0,       CSM(50),       CSM(50),     0,        0,        0, EQ(0),     0,     0, STA( 45),         0, DRV(   0,   0),      0,      0,      0,    0 },  // Didn't get the ball
  { EQ( 40),        0,             0,        GT(34),     0,        0,        0,     0,     0,     0, STA( 41),         0, DRV( 100, 100),      0,      0,      0,    0 },
  { EQ( 41),        0,  GT(MTS(700)),  GT(MTS(700)),     0,        0,        0,     0,     0,     0, STA( 42),         0, DRV( 100,-100),      0,      0,      0,    0 },
  { EQ( 42),        0,        GT(18),             0,     0,        0,        0,     0,     0,     0, STA( 10),         0, DRV(   0,   0),      0,      0,      0,    0 },  // Resume search
  { EQ( 45),        0,             0,             0,     0,        0, LT( 801),     0,     0,     0, STA( 46),         0, DRV( 100,-100),      0,      0,      0,    0 },  // Drive back to the center
  { EQ( 45),        0,             0,             0,     0,        0, GT( 800),     0,     0,     0, STA( 47),         0, DRV( 100,-100),      0,      0,      0, true },
  { EQ( 46),        0,        GT(18),             0,     0,        0,        0,     0,     0,     0, STA( 49),         0, DRV( 100,-100),      0,      0,      0,    0 },
  { EQ( 47),        0,        GT(18),             0,     0,        0,        0,     0,     0,     0, STA( 48),         0, DRV( 100, 100),      0,      0,      0,    0 },
  { EQ( 48),        0,      CSB(800),      CSB(800),     0,        0,        0,     0,     0,     0, STA( 46),         0, DRV( 100,-100),      0,      0,      0,    0 },
  { EQ( 49),        0,        GT(18),             0,     0,        0,        0,     0,     0,     0, STA( 10),         0, DRV(   0,   0),      0,      0,      0,    0 },  // Return to search
  // --- Locate the goal ----------------------------------------------------------------------------------------------------------------------------------------------
  { EQ( 90),        0,             0,             0,     0,        0,        0,     0,     0,     0, STA( 91),         0, DRV(  50,  50), ROL(1), SEG(4),      0,    0 },
  { EQ( 91),        0,  GT(MTS( 50)),  GT(MTS( 50)),     0,        0,        0,     0,     0,     0, STA( 92), TMR(1000), DRV( -70,  70),      0,      0,      0,    0 },
  { EQ( 92),        0,             0,             0,     0,        0,        0,     0,     0, LT(0),        0,         0, DRV( -70,  70),      0,      0,      0,    0 },  // Goal to the left
  { EQ( 92),        0,             0,             0,     0,        0,        0,     0,     0, GT(0),        0,         0, DRV(  70, -70),      0,      0,      0,    0 },  // Goal to the right
  { EQ( 92), EQ(   0),             0,             0,     0,        0,        0,     0,     0, EQ(0), STA( 95),         0, DRV( 100, 100),      0,      0,      0,    0 },  // Goal straight ahead
  // --- Score the goal -----------------------------------------------------------------------------------------------------------------------------------------------
  { EQ( 95),        0,             0,             0,     0,        0,        0,     0,     0,     0, STA( 96),         0, DRV( 100, 100),      0, SEG(5),      0,    0 },
  { EQ( 96),        0,             0,             0,     0, LT( 300),        0,     0,     0,     0, STA(100),         0, DRV(   0,   0), ROL(0),      0,      0,    0 },  // Goal scored, turn around
  // --- Turn around --------------------------------------------------------------------------------------------------------------------------------------------------
  { EQ(100),        0,             0,             0,     0,        0,        0,     0,     0,     0, STA(101),         0, DRV(-100, 100),      0, SEG(6),      0,    0 },
  { EQ(101),        0,        GT(34),             0,     0,        0,        0,     0,     0,     0, STA( 10),         0, DRV(   0,   0),      0,      0,      0,    0 }
};

Järgnevalt on toodud roboti main funktsioon kus käivitatakse kõik katkestustel toimuvad protsessid ja täidetakse põhialgoritmi vastavalt olekutabelist loetud väärtustele. Selles funktsioonis asub lõputu tsükkel, mis kontrollib igal läbimisel kõigis tabeli ridades olevaid sisendeid. Kui mõne tabelirea kõigis määratud sisendites on vastav väärtus, siis täidetakse samas reas kirjeldatud väljundite väärtused. Näiteks roboti käivitamiseks nupust on tabeli alguses rida, mille ainsateks sisendtingimusteks on see, et robot on peatatud ning vastavat nuppu on vajutatud. Kui need tingimused on täidetud, määratakse olekuks “2” ning robot hakkab palliotsimisprotsessiga pihta.

Enne tabeli ridade kontrollimist loetakse puhvritest kõigi andurite väärtused ning uuendatakse ka LCD ekraanil olevat infot. Et vähendada ekraani uuendamisega kaasnevat viidet on uuendamine jagatud kuue tsükli vahel, millest igas tsüklis uuendatakse erineva anduri väärtust ekraanil.

//
// Main program.
//
int main(void)
{
	unsigned char i;
	unsigned short timer;
	unsigned short encoder_left;
	unsigned short encoder_right;
	unsigned short buttons;
	unsigned short infrared;
	unsigned short ultrasonic;
	unsigned short ball;
	signed char own_goal;
	signed char target_goal;
 
	// Initial state
	unsigned short state = 1;
 
	// LCD counter
	unsigned short lcdcount = 0;
 
 	// Initialize hardware.
	init();
 
	// Loop forever
	while (true)
	{			
		// Read sensor values
		chassis_get_steps(&encoder_left, &encoder_right);
		timer       = timeout_get_counter();		  
		buttons     = sensors_buttons();
		infrared    = sensors_infrared_distance();
		ultrasonic  = sensors_ultrasonic_distance();
		ball        = sensors_is_ball();
		own_goal    = beacon_locate_own_goal();
		target_goal = beacon_locate_opponent_goal();
 
		// Display ultrasonic distance.
		switch (lcdcount % 6)
		{
			case 0:
				lcd_alpha_write_stringf_to(0,  0, "U%04d ", ultrasonic);
				break;
			case 1:
				lcd_alpha_write_stringf_to(0,  1, "I%04d ", infrared);
				break;
			case 2:
				lcd_alpha_write_stringf_to(6,  0, "M%03d ", own_goal);
				break;
			case 3:
				lcd_alpha_write_stringf_to(6,  1, "O%03d ", target_goal);
				break;
			case 4:
				lcd_alpha_write_stringf_to(12, 0, "L%03d ", encoder_left);
				break;
			case 5:
				lcd_alpha_write_stringf_to(12, 1, "R%03d ", encoder_right);
				break;
		}
		lcdcount++;
 
		pin_set_to(led_green, !ball);
		//pin_toggle(led_green);
 
		// Decide state
		for (i = 0; i < NUM_LOGIC_LIST_ITEMS; i++)
		{
			// Check input conditions match
			if (input_check_value(logic_list[i].input_state,         state) &&
				input_check_value(logic_list[i].input_timer,         timer) &&
				input_check_value(logic_list[i].input_encoder_left,  encoder_left) &&
				input_check_value(logic_list[i].input_encoder_right, encoder_right) &&
				input_check_value(logic_list[i].input_buttons,       buttons) &&
				input_check_value(logic_list[i].input_infrared,      infrared) &&
				input_check_value(logic_list[i].input_ultrasonic,    ultrasonic) &&
				input_check_value(logic_list[i].input_ball_sensor,   ball) &&
				input_check_value(logic_list[i].input_own_goal,      own_goal) &&
				input_check_value(logic_list[i].input_opponent_goal, target_goal))
			{
 
				// Set new state ?
				if (logic_list[i].output_state)
				{
					state = logic_list[i].output_state & 0x7FFF;
				}
 
				// Set timer
				if (logic_list[i].output_timer)
				{
					timeout_start(logic_list[i].output_timer & 0x7FFF);
				}
 
				// Drive ?
				if (logic_list[i].output_drive)
				{
					chassis_tank_drive((signed char)((logic_list[i].output_drive >> 8) & 0xFF),
					                   (signed char)( logic_list[i].output_drive       & 0xFF));
				}
 
				// Use roller ?
				if (logic_list[i].output_roller)
				{
					chassis_use_roller(logic_list[i].output_roller & 0x01);
				}			
 
				// Use red LED ?
				if (logic_list[i].output_led_red)
				{
					pin_set_to(led_red, !(logic_list[i].output_led_red & 0x01));
				}
 
				// Use 7-segment display
				if (logic_list[i].output_segment)
				{
					segment_display_write(logic_list[i].output_segment & 0xFF);
				}
 
				// Remember current ultrasonic reading
				if (logic_list[i].remember_usonic)
				{
					usonic_memory = ultrasonic;
				}
 
				// Got match
				break;
 
			}
		}
	}
}

Montaaž

Jalgpalliroboti kõik osad

Esimese sammuna kinnitatakse alusplaadile koodrid. Selleks läheb vaja:

  • 4 M3x10 polti
  • 8 mutrit

Kõigepealt kinnitatakse poldid mutritega alusplaadi külge, seejärel paigutatakse koodrid poltidele ning kinnitatakse need mutritega. Sel viisil tagatakse, et optokatkesti on piisavalt lähedal hammasrattale ja suudab registreerida hammasrattas olevaid auke.

1a. Alusplaat
1b. Koodrite kinnitamine alusplaadile

Koodrite täpsuse parandamiseks on hammasrattale sümmeetriliselt juurde puuritud 2 auku.

1c. Augud hammasrattas koodri jaoks

Teise sammuna kinnitatakse alusplaadi külge ultraheli kaugusandur. Selleks läheb vaja:

  • 2 10 mm kõrgust puksi (M3 keere).
  • 2 M3 polti (väikse peaga)
  • 2 mutrit
2. Ultraheli kaugusanduri kinnitamine

Kolmandana pannakse kokku rullimehhanism. Rullimehhanismi kokkupanekuks on vaja:

  • 6 M3x6 polti, 2 mootori kinnitamiseks haaratsi külge, 2 hinge kinnitamiseks haaratsi külge, 2 hinge kinnitamiseks alusplaadi külge.
  • 4 seibi, 2 mootori kinnitamisel ja 2 hinge kinnitamisel haaratsi külge.
  • 4 mutrit
  • kahepoolne teip

Esmalt kinnitatakse hing haaratsi külge. Haaratsi ja hinge vahel kasutatakse seibe, tagades sel viisil hinge vaba liikumise. Hilisem kinnitamine on raskendatud, kuna rull jääks ette.

3a. Hinge kinnitamine haaratsi külge

Järgmise sammuna kinnitatakse haaratsi külge mootor (3b). Peale seda kinnitatakse kahepoolse teibi abil haaratsi külge optiline palliandur (3c).

3b. Mootori kinnitamine haaratsi külge
3c. Optilise anduri kinnitamine

Nüüd kinnitatakse mootorivõlli otsa rull, mis fikseeritakse võllile poldiga (3d). Seejärel pannakse rullile peale kummirõngad (3e). Rullimehhanism on nüüd kokku pandud.

3d. Rulli kinnitamine võllile
3e. Kummirõngaste paigaldamine rullile

Lõpuks kinnitatakse rullimehhanism alusplaadi külge.

3f. Rullimehhanismi kinnitamine alusplaadi külge

Neljanda sammuna paigaldatakse alusplaadi külge andurite kinnitus koos infrapuna kaugusanduriga ja puksid, millele Kodulabori moodulid paigaldatakse. RC5 vastuvõtja paigaldatakse alles peale alusplaadi kinnitamist veermiku külge, kuna enneaegsel paigaldamisel saab ligipääs kruvikeerajaga raskendatud olema. Kinnituse ja pukside paigaldamiseks läheb vaja:

  • 2 M3x6 polti, andurite kinnituse paigaldamiseks
  • 4 20 mm kõrgust puksi (M3 keere).
  • 6 mutrit.
4a. Andurite kinnituse paigaldamine alusplaadile
4b. Pukside kinnitamine

Viies samm on alusplaadi kinnitamine veermikule ja RC5 vastuvõtja paigaldamine andurite kinnitusele. Selleks läheb vaja:

  • 4 M3x6 polti.
  • Kahepoolne teip.
5a. Alusplaadi kinnitamine platvormile.
5b. RC5 vastuvõtja paigaldamine.

Kuuendana kinnitatakse puksidele Kodulabori moodulid. Kinnitamiseks on vaja:

  • 4 M3x6 polti.
6. Kodulabori moodulite kinnitamine puksidele

Seitsmenda sammuna ühendatakse roboti elektroonikaosade vahel kõik juhtmed. Alustada võiks toite harukaablist mis jagab Kontrollermoodulisse minema toite kaheks millest teine pistik tuleb ühendada Mootoite mooduliga.

7a. Toitepistikute ühendamine mootori ja kontrolleri moodulile

RC5 vastuvõtja tuleb ühendada Kommunikatsioonimooduli välisesses EXT_UART pesasse:

7b. RC5 vastuvõtja ühendamine

Roomiku kaks mootorit tuleb ühendada Mootoritemooduli DC3 ja DC4 pesadesse. Koodrid lähevad sinnasamasse kõrvale ENC1 ja ENC2 pesadesse:

7c. Roomikute mootorite ja koodrite ühendamine

Edasi tuleks ühendada ultraheli- ja infrapuna kaugusandurid ning palliandur. Infrapuna kaugusanduri ja pallianduri jaoks on tarbis servode pikenduskaablit. Täpsemalt on pesad näidatud piltidel:

7d. Ultraheli- ja infrapunaanduri ühendamine. Ultraheli toide ja signaal käivad eraldi pistikutesse
7e. Pallianduri ühendamine

Viimasena on jäänud ühendada LCD kus kuvatakse programmi töö ajal kõiki andurite näitusid:

7f. Kõik moodulid omal kohal

Kaheksas ja viimane etapp on robotisse akude või patareide laadimine ning selle tööle panek. Akud käivad spetsiaalsesse alusplatvormiga kaasatulevasse rakisesse. Ühendades toitekaabli ja akuploki läheb robot tööle ja sinna saab peale laadida programmi.

8a. Akupatarei paigaldamine
8b. Roboti pingestamine
Töövalmis robot

Video

Soovitused

  • Rull teha võimalikult lai, et paremini palle kätte saada. Samas tuleb siis ka palliandur ümber teha nii, et LED ja vastuvõtja on haaratsi otses suunatud üksteise vastu ja nad jälgivad kas nende vahele satub pall.
  • Alusplaadi, rullimehhanismi haaratsi ja andurite kinnituse tegemiseks on soovitatav kasutada materjali, mille painutamisega ei oleks probleeme ning mille puhul ei oleks ohtu, et see painutamisel murdub või paindekohast praguneb. Prototüübi valmistamisel kasutatati 1 mm paksust alumiiniumi, mis antud detailide tegemiseks suurepäraselt sobis.
  • Alusplaadi, rullimehhanismi haarasti ja andurite kinnituse tegemiseks on soovitatav kasutada CNC-tööpinki. Sellega tagatakse detailide valmistamisel võimalikult väike eksimisvõimalus (nt avade puurimisel).
  • Programmi kirjutada meetod vastase robotist möödumiseks. Samas eeldab see rohkem andureid, näiteks peegeldusandurit allpool väljaku taset oleva väravapõhja tuvastamiseks.

Failid

et/projects/soccer_robot.txt · Last modified: 2020/07/20 09:00 by 127.0.0.1
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0