Tekijät: Mikael Korpinen Juha Vanhatalo AMMATILLISESTI SUUNTAAVA PROJEKTI 10.12.2010
SISÄLLYSLUETTELO Johdanto... 1 Tuotteen visio... 1 Tuotteen ominaisuudet... 5 Toteutus ja testaus... 9 Kokoamisohjeet... 12 Tarvittavat palikat:... 12 Robotin kokoaminen osissa:... 12 Robotin käyttöohje... 14 Toimintaympäristö... 14 Käyttö ja ohjaus... 14 Tehtävän Haasteellisuus... 15 Loppusanat... 16
JOHDANTO Esiprojektissa saimme tutustua Lego Groupin Mindstorms robottiin. Robotti koostui ohjainyksiköstä NXT sekä kahdesta servomoottorista ja kosketus-, värija etäisyyssensoreista. Teimme pieniä harjoituksia java-ohjelmointikielellä NXT-ohjainyksiköön, sen LeJOS-rajapinnan avulla hyödyntäen moottoreita ja sensoreita. Näin saimme tutustua robotin moottoreihin ja sensoreihin, niiden toimintaan, käyttämiseen ja mahdollisuuksiin ohjelmoinnin kautta. Tämä esiprojekti oli todella hyödyllinen ja herätti kysymyksiä ja ideoita kuten mitä pystymme tekemään? Mikä on mahdollista? Tämän jälkeen saimme tehtäväksi itse ideoida, suunnitella ja toteuttaa robotille suunnittelemamme toiminnallisuudet. Tässä dokumentissa kerrotaan projektistamme ja sen käytännön sovelluksista ja sen aiheuttamista kysymyksistä. Aloitamme ideastamme ja tästä edetään kohti itse toteutusta. TUOTTEEN VISIO Visiomme on semi-automaattisesti toimiva taistelutankki jossa yksi yksikkö ohjaa liikkumista ja toinen itse tykin ohjausta ja toimintaa, kuten ampumista. Kuvassa 1(alempana) on suuntaa antava demonstraatio tankin mallista ja toiminnasta. Tankin on tarkoitus kulkea taistelukentän läpi ennalta annettuun määränpäähän ja ampua matkalla olevia kohteita. Taistelukentällä on kahdenlaisia huomioitavia kohteita: miinoja ja esteitä. Miinat havaitaan värisensorilla ja esteet etäisyyssensorilla. Kaikki esteet paitsi miinat kaatuvat kun niihin osutaan. Taistelukentästä on havainnointikuvat kuvissa 4 ja 5. Päätimme käyttää robotin ohjaamiseen playstationin ohjainpadia. Tähän tarvittavat lisälaitteet ovat saatavilla lisätilauksella ja valmiit rajapinnat playstationin ohjainpadiin ovat valmiina LeJOS-rajapinnassa. Toinen NXTpalikka on yhteydessä playstation ohjaimeen, jolla käyttäjä voi ohjata taistelukentällä liikkumista. Tähän NXT-palikkaan on myös kytketty kaksivärisensoria, jonka avulla tankki etsii miinoja. Miinat ovat tässä tapauksessa punaisia paperin palasia lattialla. Eri valaistusolosuhteet voivat aiheuttaa ongelmia värisensorin käytössä. Tästä syystä värisensorin ympärille oli visiona tehdä pieni varjostin. Varjostuksen avulla tankin olisi ollut tarkoitus nähdä miinat myös kovassa valossa. Miinojen kohdalla tankki pysähtyy, peruuttaa ja kääntyy suunnilleen 90 astetta, jotta miinan ohi ajaminen on enemmän automatisoitua ja helpompaa. Ohjaajan tehtäväksi jää ajaa miinaan ohi. Robotissa olisi navigointijärjestelmä, jotta se tietää missä se sijaitsee. Navigoinnin avulla robotti voisi myös palata lähtöpaikkaansa itsenäisesti. 1 P a g e
Kuva 1: Luonnos taistelutankista 2 P a g e
Kuva 2Tälläinen robotti tuli Kuva 3Toinen kuvakulma 3 P a g e
Kuva 4: Taistelukenttä. Punaiset laput ovat miinoja. Vihreät ja siniset laput ovat ammuttavia esteitä. 4 P a g e
Kuva 5 Tällainen kenttä tuli loppujenlopuksi. TUOTTEEN OMINAISUUDET Taistelutankki koostuu kahdesta osasta: tykistä ja kuljetusalustasta. Tykkiin on kiinnitetty kolme moottoria. Yksi kääntelee tykkiä, toinen säätää ampumiskulmaa ja kolmas hoitaa ampumisen. Tykkiin on myös kiinnitetty mediumrange-infrapunasensori ja värisensori havainnointia varten. Tykin ominaisuutena on siis kohteiden ja esteiden etsiminen ja näiden tuhoaminen. Kuljetusalusta sisältää kaksi moottoria ja kaksi värisensoria. Kuljetusalustan tehtävänä on siis etsiä ja varoa miinoja sekä liikuttaa robottia. 5 P a g e
Taulukko 1 Robotin ominaisuudet. Ominaisuus Robotin tulee osata havaita miinoja, jotta se ei törmäisi tai ajaisin niiden yli. Robotin pitää pystyä löytämään kohteitaan. Robotin pitää pystyä ampumaan löytämiään kohteita. Testi Robotti lähetetään etenemään miinaa kohti ja varmistutaan siitä, että se pysäyttää moottorit miinan havaitessaan, peruuttaa ja kääntyy pikkaisen automaattisesti. Infrapunasensori mittaa etäisyyksiä ja niiden avulla pitäisi havaita kohde. Pyöritetään infrapunasensoria, ja kun etäisyydessä havaitaan selvä muutos, olisi siinä kohde. Kun ohjaimessa painetaan neliötä, niin robotin tykin tulee pystyä löytämään kohteen reunat ja palata kohteen keskelle varmistuttuaan että kohde on irrallaan ympäristöstä. Eli kun tykki on varmistunut kohteen aitoudesta, niin se palauttaa tähtäyksen löytämänsä kohteen keskelle. Kun robotti on löytänyt kohteen, voidaan sitä ampua ohjaimen avulla. Lisäsimme tankkiin navigointisysteemin dead reckoning -periaatteella, mutta ikäväksi yllätykseksemme huomasimme, että se ei toimi tankkimme tykin, massankeskipisteen, pölyn, telaketjujen ja painon vuoksi. Esim. kun paino on toisella puolella tykin asennon vuoksi voi telaketju sutia. Navigointiin tulee virhettä aivan liian paljon, jotta sitä voisi oikeasti käyttää. 6 P a g e
Kahden NXT-palikan välille on toteutettu langaton tiedonsiirto Bluetooth yhteydellä alemmasta ylempään. Tämä näkyy kuvasta 6. Näin voimme ohjata molempia NXT-palikoita yhdellä playstation-ohjaimella. Kuva 6 yksinkertaistettu kuva tiedonkulusta 7 P a g e
Tykkiosan NXT-palikkaan toteutetaan automaattinen tähtäys. Tykin muita ominaisuuksia, kuten tykin moottoreita ohjataan myös playstation-ohjaimella. Taistelutankki havainnoi infrapunasensorilla ympäristöä ja ilmaisee etäisyyksiä värisensorin avulla. Värisensori näyttää etäisyyden käyttäjälle erivärisinä valoina. Etäisyyksien ja valojen suhde näkyy taulukosta 2.Vihreästä sinisen kautta punaiseen on sama kuin läheltä kauas. Havaitessaan kohteen ohjaaja voi ampua sitä. Tykissä on siis automaattinen kohteen etsijä, jonka avulla saadaan ammuttua tarkasti tankin infrapunasensorilla löydettyjä kohteita. Taulukko 2 Etäisyydet ilmaistuna värisensorilla. Väri Etäisyysväli (cm) Vihreä 0-15 sinivihreävilkutus 15,1-30 sininen 30,1-45 sinipunaisenvilkutus 45,1-60 punainen 60,1-75 ei valoa > 75 Tykin kulmaa ja rotaatiota pystytään säätämään, jotta voidaan ampua muuallekin kuin eteenpäin. Tämä tekee tykistä järkevämmän, kivemman ja monipuolisemman. Useimmiten tykin liipaisimen painaminen ja kulman säätö on aina ihmisen käsissä, koska ampuminen on kivaa. Jos infrapunasensorin etäisyys olisi pidempi, niin olisimme voineet tehdä vielä kulman ja etäisyyden mittaavan toiminnon, jotta ammus lentäisi kohteeseen asti. Robotissa on viisi moottoria, kolme värisensoria, mediumrange-infrapunasensori sekä playstationohjain ja ohjaimen signaalin vastaanotinsensori. 8 P a g e
TOTEUTUS JA TESTAUS Olemme rakentaneet robotista lopullisen version, jolla pääsemme testaamaan liikkumista. Koska meillä oli ongelmia bluetooth-yhteyden kanssa, suuri osa ajasta on mennyt sen ongelman ratkaisemiseen. Jostain syystä tietokoneen NetBeans-ohjelmointityökalulla emme saa ladattua ohjelmistoja langattomasti bluetooth:lla robottiin, vaikka laiteparit on muodostettu. USB-yhteydellä saamme robotin ohjelman kuitenkin ladattua. Tosin testaus ja säätäminen ovat hieman hitaampaa ja hankalampaa. Aluksi suunnittelimme ohjata robottia tietokoneella, joten lähdimme toteuttamaan tietokoneen ja robotin välistä yhteyttä. Yksinkertaisella tekemällämme käyttöliittymällä saimme ohjattua käskyn robottiin. Käyttöliittymä toimi MV-mallin pohjalla tietokoneella, jossa myös bluetooth-yhteyden luonti ja hallinta olivat toteutettuna. Myöhemmin kun saimme Playstation-ohjaimen käyttöömme, aloimme tutkia sen rajapintaa. LeJOS API tarjoaa Playstation-ohjaimen käyttöön muutamat yksinkertaiset valmiit metodit PSPNXController-luokassa. Käytettävät metodit näkyvät taulukossa 3. Taulukko 3 PSPNXController-luokan metodit short getbuttons() Jokainen bitti short:ssa esittää napin boolean-arvoa. (painettu tai ei painettu) byte getleftx() byte getlefty() byte getmode() Palauttaa sensorinnykyisen operointi tavan. byte getrightx() byte getrighty() int powerup(boolean activate) int setadpamode(boolean activate) int setdigitalmode(boolean activate) Haasteena oli yhdistää metodit ja niiden palauttamat arvot ohjaimen napin painalluksiin. Taulukossa 3 nähtävä getbuttons()-metodi palauttaa 16-bittisen short-tyyppisen muuttujan, jossa jokainen bitti esittää jonkin napin booleanarvoa. Eli onko nappi painettu vai ei. getleftx()- ja getlefty()-metodit palauttavat ohjaimen vasemman tatin arvot byte-arvona. getrightx()- ja getrighty()-metodit palauttavat oikean puolen tatin arvot byte-arvona. Hieman ongelmia aiheutti short ja byte muuttujien tulkinta Java:ssa, mutta muuttamalle ne int-tyyppisiksi bittioperaatioilla saimme niistä lopulta selkoa. 9 P a g e
Robottimme koostuu kahdesta NXT-palikasta, mutta playstation-ohjaimen vastaanotin voidaan kytkeä vain yhteen NXT-palikkaan. Jotta voisimme ohjata molempia NXT-palikoita, teimme niiden välille langattoman bluetoothyhteyden. Näin saamme ohjattua myös toista osaa epäsuorasti. Alustavasti saimme onnistuneesti testattua kokonaislukujen siirtoa kahden NXT-palikan välillä bluetooth-yhteyden avulla edestakaisin.tästä teimme oman merkinantoprotokollan NXT-palikoiden välille, jotta tykkiosan ohjaus olisi mahdollista. Kuljetusalustan NXT-palikkaan on kytketty ohjaimen vastaanotin. Ohjaimelta vastaanotettu data tulkitaan alaosassa, eli kuljetusalustassa, joka välittää tykin ohjaamiseen liittyvät tiedot yläosaan. Robotin ohjaamiseen liittyvät tiedot tulkitaan suoraan robotin liikuttamiseen alaosassa. Tykin ohjaamiseen liittyvät tiedot tulkitaan yläosassa sovelluspuolella käskyiksi yläosan moottoreille. Robotin liikuttamisen teimme SimpleNavigator- ja Pilot-luokkien rajapintojen avulla. Näin saimme robottiin navigointi-ominaisuuden dead reckoning - periaatteella. Näiden rajapintojen avulla robotti laskee sijaintitietoja servomoottoreiden kierroksien mukaan. Näin robotti voidaan käskeä liikkumaan haluttuihin koordinaatteihin itsestään. Robotin alaosassa olevat kaksi värisensoria etsivät punaista, ettei robotilla voi ajaa niiden yli. Värisensorien toiminta on toteutettu lejos.robotics.colors-rajapinnan avulla. Kun robotti näkee punaista, se tekee automaattisesti pakotetun väistöliikkeen peruuttaen ja kääntyen. Tykkiosa vastaanottaa alaosalta tykin ohjausdataa ja kääntää ne käskyiksi tykin servomoottoreille. Tykin liikuttelu toteutettiin yksinkertaisilla moottorinohjauskäskyillä. Tykkiosassa on myös infrapunasensori, jolla mitataan etäisyyksiä. Tähän toteutimme automaattisen tähtäyksen. Automaattinen tähtäys liikuttaa tykkiosaa hitaasti oikealle ja mittaa etäisyyksiä. Etäisyyksistä päätellään mahdollinen kohde. Kohde tunnistetaan kun etäisyyksissä tapahtuu huomattava muutos. Kun kohde on tunnistettu, tykki kohdistuu kohteen keskiosaan ja antaa äänimerkkinä kaksi piippausta. Tämä automaattinen tähtäys helpottaa huomattavasti kohteeseen osumista, vaikka se onkin hidas. Visiossa mainitun varjostimen hylkäsimme turhana ominaisuutena annetuissa olosuhteissa. 10 P a g e
Taulukko 4 Toiminnot ja testit. Ominaisuus Toiminto Testi Testin tulos Aika Bluetooth yhteys Tietokoneen ja NXT-palikan välinen langaton kommunikointi molempiin suuntiin. Tiedonsiirto edestakaisin. kokonaisluvuilla OK JV:3 MK:3 MV-tietorakenne(nykyään käytössä) ei Eri luokkien välinen kommunikointi. Ohjaus Robotin ohjaus playstation ohjaimen avulla. Playstation ohjaimen toiminta. Robottia ohjataan ohjaimen avulla. Bluetooth yhteys kahden NXTpalikan välillä. Langaton tiedonsiirto kahden NXT-palikan välillä edestakaisin. Käyttöliittymä sovelluslogiikan kanssa. toimii Robotti liikkui ohjaimen nappia painamalla. Tutkittu ohjaimen rajapinnan toimintoja ja yhdistetty niitä robotin ohjaamiseen. Tiedonsiirto edestakaisin. kokonaisluvuilla Tykillä ampuminen Pienen pallon ampuminen Tykillä ammutaan kun ohjaimen nappia painetaan. Värisensorien käyttö Värisensorin toiminto Värisensorin havaitessa punaista robotti pysähtyy Behaviour toiminta. ohjelmointimallin Behaviour-toimintojen vaihtelu Ladataan käyttäytymisiä OK Instance-luokan mukaan. tietorakenteeseen ja käynnistetään arbitrator Infrapunasensorin etäisyyksien mittaus ja niiden ilmaisu värisensorin avulla. Kohteiden etsintä toiminto infrapunasensorin avulla. Infrapuna tutkii etäisyyksiä ja etäisyydet käännetään väreiksi tykissä olevaan värisensoriin. Automaattinen tähtäys. Navigation Tankin tulisi osata palata lähtöpaikkaansa. Frenzy mode siirretään kappaleita kauas ja lähelle. Katsotaan palavatko oikeat värit oikeilla etäisyyksillä OK OK OK MK:2 JV:4 MK:2 JV:9 MK:9 OK JV: 5 OK OK OK Kun väri ei pala niin tiedetään OK että kohteita ei ole infrapunasensorin maximi etäisyydellä. Tämän jälkeen painetaan neliötä joka käynnistää kohteiden etsintä moodin. Kun kohde löytyy tulee tykin palata löydetyn kohteen keskelle, nostaa tykkiä hieman ja piipata kahdesti. Painetaan ympyrää ja katsotaan meneekö tankki haluttuun kohtaan. Toiminto epäonnistui tankin painon, massakeskipisteen, telaketjujen ja lian/pölyn vuoksi. fail JV:3 MK:3 JV:2 MK:2 JV:4 MK:6 MK:3 JV:8-10 MK:4-5 JV:2-3 MK: 0.5-1 11 P a g e
KOKOAMISOHJEET Tarvittavat palikat: -5 servo moottoria -1 Infrapunasensori -3 värisensoria -2 NXT-palikkaa -Playstation ohjaus setti -Telaketjut -Neljä vannetta -Paljon erilaisia rakennus lego palikoita -Lego palikat osien yhdistämiseen, telaketju systeemiä varten, tykin eli yläosan tukemista varten, ja tykkiin ammusvarastoa varten. Robotin kokoaminen osissa: Ensikisi alusta. Alusta koostuu kahdesta servomoottorista, kahdesta värisensorista, kahdesta NXT-palikasta ja Playstation-vastaanottimesta. Rakennetaan pohja eli kaksi servomoottoria ja lego palikat joilla kaikki yhdistetään jotta voidaan kulkea eteenpäin. Asennetaan NXT-palikka robotin perälle. Etuosaan liitetään playstation-ohjaimen vastaanotin ja kaksi värisensoria. Kun nämä on suoritettu, niin rakennetaan pohjan päälle tukiteline tykille tukemaan robotin yläosaa eli tykkiä kun se pyörii ympäri. Kuva 7 Tankin alaosa Huom! Tukiteline ja osa johon tykki kiinnitetään(keskellä). 12 P a g e
Toiseksi yläosa Yläosan rakenne on nähtävissä kuvassa 8. Rakennetaan tykin eli yläosan NXTpalikkaan legopalikoista teline, jolla ensimmäinen moottori saadaan kiinni palikkaan. Tämän jälkeen Tehdään palikoista systeemi, jolla saadaan toinen moottori järkevästi ensimmäiseen moottoriin kiinni. Tämä toinen moottori on se joka hoitaa ampumisen ja ensimmäinen hoitaa tykin kulman säätelyn. Tykin ampujamoottoriin tulisi saada myös kiinnitettyä infrapunasensori niin lähelle tykkiä kuin mahdollista. Tykki tulisi myös saada mahdollisimman alas, jottei tarvitsisi ampua alaviistoon. Kolmas moottori kytketään yläosaan NXT-palikan pohjaan. Tämä voidaan tehdä myös ennen yläosan tykin eli ammunta systeemin kokoamista. Tämän moottorin tulee olla mahdollisimman sivussa sillain että se tasapainottaa toisella puolella olevan tykin painoa ja täten siirtää massan keskipistettä lähemmäksi yläosan palikan ja tankin keskiosaa. Tykki liitetään alustaan ja tykin alamoottorin perä eli se puoli jossa ei ole pyörivää osaa asetetaan nojaamaan alaosa tukitelinettä vasten. Tällä ovelalla systeemillä siirretään suurin osa painosta tukitelineeseen jotta moottorit toimivat paremmin eikä ne hajoa. Tykki ja alusta painavat paljon! Teimme tykkiosan moottoriin joka säätelee kulmaan pienen tasapainottavan vastapainon, jossa on kiinni kaksi rengasta tasapainottamassa moottoriin kohdistuvaa painoa, jotta moottori toimisi herkemmin. Värisensori kiinnitetään palikan toiselle puolelle, eli tässä tapauksessa vasemmalle. Sensorit kuvassa 8 tunnistaa niistä lähtevistä johdoista. Kuva 8 NXT-palikan yläosa eli tykki. Huom! Infrapunasensori tykin vieressä! 13 P a g e
ROBOTIN KÄYTTÖOHJE Toimintaympäristö Robotin toimintaympäristöön olemme suunnitelleet ammuttavia kohteita ja miinoja. Miinat ovat lattialla olevia punaisia pahvinpalasia. Robotti toimintaympäristö on nähtävissä kuvasta 5. Kuvassa pystyssä olevat sienet ovat ammuttavia kohteita. Taustalla taas olevat pahvisotilaat ja tankit ovat rekvisiittaa ja harjoitus kohteita jos vierailijat haluavat ammuskella ja kokeilla tankin toimintoja. Käyttö ja ohjaus Robottia ohjataan playstation-ohjaimella. Ohjain on nähtävissä kuvassa 9 ja nappuloita vastaavat toiminnot ovat nähtävissä taulukossa5. Kuva 9 Ohjain. 14 P a g e
Taulukko 5 Ohjaimen toiminnot. Ylös Eteenpäin L2 Tykki vasemmalle Vasen Kääntyy vasemmalle R2 Tykki oikealle Oikea Kääntyy oikealle L1 Tykki alas Alas Taaksepäin R1 Tykki ylös Vasen tatti Robotin ohjaus Ampuminen Automaattinen tähtäys Kotiin tulo Oikea tatti Tykin ohjaus TEHTÄVÄN HAASTEELLISUUS Tehtävän haasteina olivat ideoiden muuttaminen toimiviksi. Isona haasteena on ollut toimintojen hahmottaminen ja niiden ohjelmointi annettavassa ajassa. Meillä oli monta kysymystä siitä mitä pystymme tekemään annetussa ajassa ja mitä emme. Teimme tankista monta versiota ja loppujenlopuksi saimme mallin joka oli molempien mielestä toimiva ja esteettisesti miellyttävä. Ehkä isoin ongelma tankkia tehdessämme oli tykin tekeminen. Tykki piti saada mahdollisimman alas ja liikkumaan vapaasti. Kolmen moottorin ja NXTpalikan syystä tykistä tuli painava mikä aiheutti paljon ongelmia niin tähtäyksessä kuin tasapainossa. Piti saada aikaan malli joka ei ole vinossa ja epälooginen. Tankkia koodatessa meillä oli myös hyvää onnea siinä, että ohjaimelle löytyi valmis rajapinta. Tosin sen käyttö vaati paljon testausta ja opettelua. Tankkia koodatessamme huomasimme myös että asetukset kuten nopeus, tähtäyksen tarkkuus ja automaattiset toiminnat vaihtuivat tykin asennon ja pattereiden kulumisen vuoksi. Huomasimme myös, että kun patterit olivat ladattu täyteen niin tankki ei toiminut asettamillamme asetuksilla aluksi. Tämä aiheutti jatkuvaa hienosäätöä. Tämän lisäksi patterit tuntuivat huononevan projektien edistyessä. Kysymykseksi jäi: Johtuiko tämä pattereiden käytöstä ja niiden kulumisesta huonommaksi vai söikö palikoiden väliset yhteydet ja toiminnot loppujen lopuksi niin paljon, että pattereiden tehot eivät riittäneet kuin muutamiksi tunneiksi? Projektin alussa patterit kestivät useita päiviä, mutta lopussa vain muutamia tunteja. Asiaa miettiessämme huomasimme, että alaosa kulutti pattereita vähemmän, vaikka siihen oli kytketty langattoman ohjaimen vastaanotin, kaksi värisensoria, yhteys ylempään NXT-palikkaan ja kaksi moottoria. Myös ohjain tuntui syövän pattereita paljon. Bluetooth yhteyksien 15 P a g e
kanssa oli jo alusta asti ongelmia. Tietokoneella ei saatu yhteyttä alempaan palikkaan joten jouduimme tankkaamaan ohjelmiston robottiin. Ylempään palikkaan taas yhteys onnistui paitsi esittelytilaisuudessa, jolloin tietokone otti yläpalikkamme sijaan yhteyden ope nimiseen kohteeseen. Tämä ongelma jäi auki. Mikä oli se ope laite? Miksi yhteys muodostui juuri tähän? Aiheuttiko se että oli niin monta robottia ja tietokonetta kerralla luokassa ja tämän vuoksi otti yhteyden johonkin vanhaan ope laitteeseen? Vai oliko ope kyseenomaisen palikan entinen nimi? LOPPUSANAT Vasta tankin rakennettuamme aloimme ymmärtää mitä kaikkea olisimme voineet tehdä ja mitkä olisivat hienoja lisä ominaisuuksia. Loppujenlopuksi onnistuimme mielestämme erittäin hyvin lukuun ottamatta navigoinnin epäonnistumista. Emme ikinä olisi onnistuneet tehtävässä ilman onnistunutta ryhmätyötä ja kommunikointia. Lisäksi teimme jotain uutta ja vietiin kehitystä kurssin puolelta eteenpäin. Otimme riskin ja onnistuimme. Projektin tekeminen oli hauskaa ja haastavaa. Jos aikaa olisi ollut enemmän, olisimme voineet tehdä myös kehittyneemmän kohteenetsintäalgoritmin. Tämän puuttuminen jäi harmittamaan. Kiitokset opettajille ja ryhmäläisille kaikesta. Ilman opettajien antamaa materiaalia ja opiskelijoiden antamaa palautetta olisi ollut vaikeata onnistua hyvin kyseenomaisesta tehtävästä annetussa ajassa. Tämä ammatillisesti suuntaava projekti on ollut ehkä mielenkiintoisimpia ja antoisampia kursseja tähän asti. Oli mielenkiintoista nähdä myös mitä kaikki muut saivat aikaan ja miten. 16 P a g e