Antitammirobotti Antti Meriläinen <antti.merilainen@helsinki.> Martin Pärtel <martin.partel@cs.helsinki.> 29. toukokuuta 2009 Helsingin yliopisto Tietojenkäsittelytieteen laitos Robottiohjelmoinnin harjoitustyö (Java) Ohjaaja Mikko Apiola Helsingissä 20.05.2009
Sisältö 1 Robotin rakenne ja toimintaperiaate 1 2 Toteutus ja sen ongelmat 2 3 Ohjelman osat 2 3.1 Pääohjelma............................ 2 3.2 Käytösluokat........................... 3 3.3 Robotin liikuttelukoodi...................... 3 3.4 Valoanturidatan tulkitseminen.................. 3 3.5 Peliabstraktio........................... 3 3.6 Tekoäly.............................. 3 3.7 Apuluokkia ja tietorakenteita.................. 4 4 Sivuttaisliike 5 5 Tarvittuja ohjelmointikurssien taitoja 6 6 Lähdekoodi 6
1 Robotin rakenne ja toimintaperiaate Tämän epäonnistuneen projektin tavoite oli toteuttaa tammea pelaava Lego Mindstorms NXT -robotti. Robotti liikkuu pelilaudan yli pyörillä ja liu'uttaa käsivarttaan laudan rivien yli. Käsivarressa on kiinteä valoanturi laudan tilan lukemista varten sekä moottorilla laskettava nappulanliikuttaja. Robotin kanssa pelataan vuorotellen siten, että ihmispelaaja painaa vuoronsa jälkeen robotin nappulaa, jonka jälkeen robotti lukee laudan tilan ja tekee oman siirtonsa. Tavallisen tammen sääntöjen mukaan nappula muuttuu laudan loppuun päätyessään tammeksi. Tammea merkitään yleensä kahdella päällekkäisellä nappulalla. Pelin sääntöjä muutettiin, koska robotti ei kykene helposti merkitsemään eikä tunnistamaan tamminappulaa. Uusissa säännöissä nappulat 1
eivät voi edetä päästyään laudan loppuun asti. Myös pelin tavoite käännettiin päinvastaiseksi: ensimmäinen pelaaja, joka ei voi enää tehdä siirtoja, on voittaja. 2 Toteutus ja sen ongelmat Robotin rakenteen kenties suurin ongelma oli käsivarren liu'uttajan liikerata. Liike oli melko epätarkka ja hitailla nopeuksilla nykivä. Moottorin asento ja käsivarren etäisyys moottorista olivat epälineaarisessa riippuvuussuhteessa. Lisäksi moottorin käynnistäminen ja pysäyttäminen vaikutti käsivarren liikkeeseen pienellä viiveellä. Kaikkien näiden tekijöiden huomioiminen ohjelmassa luotettavalla tavalla osoittautui liian vaikeaksi. Legon valosensori erottaa valitettavasti vain harmaasävyjä. Robotin täytyi kyetä erottamaan toisistaan mustat ja valkoiset nappulat sekä laudan musta reuna. Laudan pienen koon, sivuttaisliikeen epätasaisuuden ja muiden epätarkkuustekijöiden takia laudan lukeminen riittävän luotettavasti ei onnistunut. Robotin tekoäly toteutettiin alfa-beeta -karsinnalla tehostetulla minimax -algoritmilla. Pelipuun tutkintaa rajoitettiin vakiosyvyyteen, jossa laudan tila pisteytettiin yksinkertaisella heuristiikalla. Tekoäly toimi kohtalaisen hyvin. 3 Ohjelman osat Kaikki koodi sijaitsee pakkauksessa lego. 3.1 Pääohjelma Pääohjelman lego.main tehtävä on alustaa lejosin käytös rajapinta (behaviour API). lego-pakkauksen juuressa on myös muita pikaisiin kokeiluihin käytettyjä pääohjelmia. 2
3.2 Käytösluokat Koska projekti jäi kesken, käytösluokkia toteutettiin vain yksi: lego.behaviors.initialboardscan, jonka tehtävä on lukea laudan tila uudestaan. 3.3 Robotin liikuttelukoodi Robotin liikutteluun tarvittava apukoodi sijaitsee lego.control -pakkauksessa. MotorControl -rajapinta määrittää yhteisiä metodeja, jotka toteutettiin jokaiselle liikesuunnalle (HandControl, SidewaysControl, WheelControl). Sivuttaisliikkeen epälineaarisuuden kompensointi piilotettiin SidewaysControl -luokkaan. RobotControl sisältää em. MotorControl:n toteutukset sekä koodin rivien tai sarakkeiden skannaukseen. 3.4 Valoanturidatan tulkitseminen RobotControl:n skannausmetodit tuottavat taulukon valoanturin arvoja. Näiden arvojen tulkitsemiseen tarvittavat algoritmit sijaitsevat BoardScan- Data -luokassa. Koodi tulkitsee valoanturidataa käyränä ja etsii sieltä riittävän pitkiä tasaisia osia (BoardScanData.Segment). Näistä osista kaksi tumminta tulkitaan laudan reunoiksi ja loput tulkitaan joko laudaksi tai nappuloiksi. 3.5 Peliabstraktio Tammipeliä mallintavat luokat ovat lego.checkers -pakkauksen Board, Simple- Move ja JumpSequence. Laudan koordinaatistossa numeroidaan kaikki kahdeksan riviä (0-7), mutta sarakkeissa numeroidaan vain mustat ruudut (0-4). 3.6 Tekoäly Tekoäly sijaitsee luokassa lego.checkers.ai.minimaxai. Tekoälylle sopivat heuristiikat sijaitsevat lego.checkers.ai.heuristic -pakkauksessa ja to- 3
teuttavat PositionEvaluator -rajapinnan. 3.7 Apuluokkia ja tietorakenteita lego.misc -pakkauksessa on sekalaisia apuluokkia sekä joidenkin Lejosista puuttuvien tietorakenteiden toteutuksia. 4
4 Sivuttaisliike Sivuttaisliikkeessä täytyi ratkaista moottorin kulmaa ja käsivarren sijaintia yhdistävä kaava. Halutaan siis ratkaista pituus X kulman α funktiona. Voidaan kirjoittaa: X = X 1 + X 2 ja X 1 = H 1 cos(π α) = H 1 cos(α). Pituus X 2 voidaan ratkaista, kun tiedetään: X 2 2 + Y 2 4 = H 2 2 X 2 2 = H 2 2 Y 2 4 X 2 = Lisäksi tiedetään, että: H 2 2 Y 2 4 Y 1 + Y 3 = Y 2 + Y 4 Y 4 = Y 1 + Y 3 Y 2 = Y 1 Y 2 + H 1 sin(π α) = Y 1 Y 2 + H 1 sin(α) Saadaan lopuksi: X = X 1 + X 2 = H 1 cos(α) + H2 2 Y4 2 = H 1 cos(α) + H2 2 (Y 1 Y 2 + H 1 sin(α)) 2 missä Y 1, Y 2, H 1 ja H 2 ovat vakioita. 5
5 Tarvittuja ohjelmointikurssien taitoja Välttämättömiä taitoja Algoritmien laatimisen perusteet Algoritmien aika- ja tilavaativuuden arviointi Rekursion käyttö algoritmeissa Olio-ohjelmoinnin perusteet: kapselointi ja perintä Hyödyllisiä taitoja Polymorsmin hyödyntäminen Roskienkerääjän olemassaolon tiedostaminen Säikeet (Rinnakkaisohjelmointi, Ohjelmointitekniikka (Java)) 6 Lähdekoodi Robotin ohjelman lähdekoodi ulkoisine kirjastoineen sijaitsee hakemistossa lego/ ja sen alihakemistoissa. lego-extra/ sisältää joitakin yksikkötestejä sekä käyttöliittymän tekoälylle. Ohjelmaa kehitettiin Eclipse 3.4.1 -kehitysympäristössä käyttäen lejos-kirjaston Eclipse-liitännäistä. 6