Osien koodaus tehdään ennalta sovitun tyylin mukaisesti.
Toteutus on jaettu seuraaviin tiedostoihin:
fys/autodata.h tietoja auton ominaisuuksista
fys/fmauto.cpp fysiikkamallin auto-luokan toteutus
fys/fmauto.h määrittelyt fysiikkamallin luokasta auto
fys/vektori.cpp vektoriluokan toteutus
fys/vektori.h vektoriluokan määrittelyt
fys/FmRata.h ratavektorien tutkimisen optimointiin käytettävä luokka
fys/FmRata.cpp ratavektorien tutkimisen optimointiin käytettävä luokka
laitteet/nastat.h tiedot toimilaitteiden nastajärjestyksestä
laitteet/tlanturi.h määrittelyt luokalle TlAnturi
laitteet/tldata.h tietoja toimilaitteiden ominaisuuksista
laitteet/tlfotodi.cpp TlFotodiodi-luokan toteutus
laitteet/tlfotodi.h määrittelyt luokalle TlFotodiodi
laitteet/tlkaynni.cpp toteutus luokalle TlKaynnistysnappi
laitteet/tlkaynni.h määrittelyt luokalle TlKaynnistysnappi
laitteet/tlkulmap.cpp toteutus luokalle TlKulmapotentiometri
laitteet/tlkulmap.h määrittelyt luokalle TlKulmapotentiometri
laitteet/tllaitte.cpp TlLaitteet-luokan toteutus
laitteet/tllaitte.h TlLaitteet-luokan määrittelyt
laitteet/tlledika.cpp toteutus luokalle TlLedikampa
laitteet/tlledika.h määrittelyt luokalle TlLedikampa
laitteet/tlmooser.cpp toteutus luokalle TlMoottoriservo
laitteet/tlmooser.h määrittelyt luokalle TlMoottoriservo
laitteet/tlmootto.cpp toteutus luokalle TlMoottori
laitteet/tlmootto.h määrittelyt luokalle TlMoottori
laitteet/tlnopeus.cpp toteutus luokalle TlNopeusanturi
laitteet/tlnopeus.h määrittelyt luokalle TlNopeusanturi
laitteet/tlohjser.cpp toteutus luokalle TlOhjausservo
laitteet/tlohjser.h määrittelyt luokalle TlOhjausservo
laitteet/tlservo.cpp toteutus luokalle TlServo
laitteet/tlservo.h määrittelyt luokalle TlServo
laitteet/tltoimil.h määrittelyt luokasta TlToimilaite
laitteet/prosu/prosu.cpp auton käsiohjauksessa prosessoria matkivan osan toteutus
laitteet/prosu/prosu.h auton käsiohjauksessa prosessoria matkivan osan määrittely
kayttoliittyma/KlKonsoli.cpp käyttöliittymän luokan KlKonsoli toteutus
kayttoliittyma/KlKonsoli.h määrittelyt luokalle KlKonsoli
kayttoliittyma/KlPaataso.cpp käyttöliittymän KlPaataso-luokan toteutus
kayttoliittyma/KlPaataso.h määrittelyt luokalle KlPaataso
kayttoliittyma/KlRekisterit.cpp käyttöliittymän KlRekisterit-luokan toteutus
kayttoliittyma/KlRekisterit.h määrittelyt luokalle KlRekisterit
kayttoliittyma/uCC.cpp pääohjelma
kayttoliittyma/uCC.h ohjelman yhteisiä määrityksiä
kayttoliittyma/KlMuisti.cpp käyttöliittymän KlMuisti-luokan toteutus
kayttoliittyma/KlMuisti.h määrittelyt luokalle KlMuisti
kayttoliittyma/KlRata.cpp käyttöliittymän KlRata-luokan toteutus
kayttoliittyma/KlRata.h määrittelyt luokalle KlRata
kayttoliittyma/pixmaps/ käyttöliittymän pixmap-hakemisto
kayttoliittyma/auto/KlAkselit.cpp KlAkselit-luokan toteutus
kayttoliittyma/auto/KlAkselit.h määrittelyt luokalle KlAkselit
kayttoliittyma/auto/KlAutonKomponentti.cpp tässä luokassa on auton eri piirrettävien osien yhteiset ominaisuudet
kayttoliittyma/auto/KlAutonKomponentti.h määrittelyt luokalle KlAutonKomponentti
kayttoliittyma/KlDisassembler.h disassemblerin määrittelyt
kayttoliittyma/KlDisassembler.cpp disassemblerin toteutus
kayttoliittyma/auto/KlNopeus.cpp KlNopeus-luokan toteutus
kayttoliittyma/auto/KlNopeus.h määrittelyt luokalle
kayttoliittyma/auto/KlAnturi.cpp KlAnturi-luokan toteutus
kayttoliittyma/auto/KlAnturi.h määrittelyt luokalle KlAnturi
kayttoliittyma/auto/KlKitka.cpp KlKitka-luokan toteutus
kayttoliittyma/auto/KlKitka.h määrittelyt luokalle KlKitka
kayttoliittyma/auto/KlRenkaat.cpp KlRenkaat-luokan toteutus
kayttoliittyma/auto/KlRenkaat.h määrittelyt luokalle KlRenkaat
kayttoliittyma/auto/KlAuto.cpp KlAuto-luokan toteutus
kayttoliittyma/auto/KlAuto.h määrittelyt luokalle KlAuto
kayttoliittyma/auto/KlMoottori.cpp KlMoottori-luokan toteutus
kayttoliittyma/auto/KlMoottori.h määrittelyt luokalle KlMoottori
kayttoliittyma/auto/Koordinaatti.cpp Koordinaatti-luokan toteutus
kayttoliittyma/auto/Koordinaatti.h määrittelyt luokalle Koordinaatti
68hc11/CPU.h MkCPU-luokan (mikrokontrollerin CPU)
määrittelyt
68hc11/CPU.cpp MkCPU-luokan toteutus
68hc11/IO-laitteet.h MkIO_laitteet-luokan (muisti, timer, AD-
muunnin, pulse accumulator, keskeytykset)
määrittelyt
68hc11/IO-laitteet.cpp MkIO_laitteet-luokan toteutus
68hc11/liitantarima.h MkLiitantarima-luokan (prosessorin ja auton
välinen liitäntärima) määrittelyt
68hc11/liitantarima.cpp MkLiitantarima-luokan toteutus
mkohjaus/ohjaus.h luokan MkOhjaus määrittelyt
mkohjaus/ohjaus.cpp luokan MkOhjaus toteutus
mkohjaus/breakpoint.h luokan MkBreakpoint määrittelyt
mkohjaus/breakpoint.cpp luokan MkBreakpoint toteutus
mkohjaus/loki.h luokan MkLoki määrittelyt
mkohjaus/loki.cpp luokan MkLoki toteutus
mkohjaus/rekehdot.h MkRekEhdot luokan määrittelyt
mkohjaus/rekehdot.cpp MkRekEhdot luokan toteutus
mkohjaus/ehto.h luokan MkEhto ja siitä periytyvien luokkien määrittelyt
mkohjaus/ehto.cpp luokan MkEhto ja siitä periytyvien luokkien toteutus
mkohjaus/lista.h luokkien MkLista_alkio ja MkLista määrittelyt
mkohjaus/lista.cpp luokkien MkLista_alkio ja MkLista toteutus
mkohjaus/pino.h luokan MkPino määrittelyt
mkohjaus/pino.cpp luokan MkPino toteutus
rata/Deque.cpp kahteen suuntaan linkitetyn listan toteutus
rata/Deque.h määrittelyt luokalle Deque
rata/Rata.cpp radan toteutus
rata/Rata.h määrittelyt luokalle Rata
rata/OptRata.h riisuttu versio radasta (optimointia varten)
rata/OptRata.cpp riisuttu versio radasta (optimointia varten)
rata/VektoriDeque.cpp luokan VektoriDeque toteutus
rata/VektoriDeque.h määrittelyt luokalle VektoriDeque
Keskeytyksiin liityvät käskyt wai, swi ja rti on lisätty. Stop-käskyssä on otettu huomioon stop disabled-bitti, mitä ei valmiissa koodissa ollut tehty. Lisäksi valmiiseen koodiin on tehty huomattava määrä erilaisia korjauksia, koska siinä oli aika paljon virheitä.
Keskeytykset tarkistetaan jokaisen käskyn suorituksen jälkeen.
Output comparet, pulse accumulator ja AD-muuntimen arvot päivitetään
liitäntärimaan aina käskyn suoritusten välillä, jolloin
virhe ohjauspulssien pituudessa on pahimmillaan 41 kellojaksoa = n. 20 us
(FDIV, IDIV). Tästä
ei aiheudu kovin suurta virhettä, koska ohjauspulssien ja nopeusanturin
pulssien pituudet ova millisekunteja.
Suojattujen kontrollirekisterien muuttamista ei tarvitse toteuttaa, koska ei ole mitään tarvetta voida vaihtaa rekisterien ja muistin osoitteita. Niiden arvoja ei siis voi muuttaa manuaalissa kerrotun 64 ensimmäisen kellojaksonkaan aikana. COP watchdog -systeemiä ei ole toteutettu.
Simulaattori toimii normal expanded -moodissa ja suorittaa yhden käskyn kerrallaan. Resetin jälkeen PC:n alkuarvo haetaan reset-vektorista (0xFFFE, 0xFFFF).
Valmiista C-koodista on tehty pienehköillä muutoksilla oma luokkansa, jossa on toteutettu CPU:n toiminta. Kuluneet kellojaksot, rekisterien arvot ja tilaliput ovat prosessorin tilaa kuvaavassa tietueessa.
Testaus on suoritettu kahdella Tampereelta saadulla valmiilla ohjausohjelmalla, sekä näistä itse tehdyillä muunnelmilla. Satunnainen heksakoodi (esim. ohjelman data-alueen suorittaminen) pysäyttää simulaattorin niin kuin pitääkin. Testauksessa käytettiin mm. ohjelmaa, joka kääntää pyörät ääriasentoon ja moottorin tehon täysille sekä ohjelmia, jotka ainakin yrittävät seurata rataa. Pelkän CPU:n testauksessa on käytetty simulaattorin alkuperäisestä käyttöliittymästä tehtyä testiohjelmaa, jossa näkyvät rekisterien ja muistin sisältö ja seuraavaksi suoritettava käsky. Aivan yhtä hyvin testaamisen voi suorittaa nykyisellä käyttöliittymällä nyt kun se on valmis.
// MkOhjaus::SuoritaKasky
// Funktio kutsuu luokan MkCPU funktiota Suorita_kasky. Jos Suorita_kasky
// palauttaa ilmoituksen jonkunlaisesta virheestä, ilmoitus palautetaan heti
// käyttöliittymälle, eikä tehdä muuta. Jos CPU suoritti käskyn virheettömästi :
// - Käyttöliittymälle välitetään alusta (CPU:n luomisesta) asti kulunut aika
// sekunneissa.
// - Toimilaitteille välitetään alusta asti kulunut aika sekunneissa jos siitä, kun
// toimilaitteita viimeksi kutsuttiin on kulunut vähintään 20 kellojaksoa.
// - Tarkastetaan onko lokitulostus päällä ja jos on, kutsutaan funktiota
// MkLoki::Kirjota, joka kirjottaa tarvittavat tiedot lokiin.
// - Tarkastetaan onko breakpoint-tarkastus päällä ja jos on kutsutaan funktiota
// MkBreakpoint::Tarkasta, joka huolehtii tarvittavista tarkastuksista
// Funktion paluuarvot:
// 0 käsky suoritettu onnistuneesti, ei breakpointia
// 1 breakpoint
// 2 CPU ilmoitti virheestä
Tiedostojen ohjaus.h ja ohjaus.cpp ja niissä toteutetun luokan MkOhjaus kautta tapahtuu suurin osa Debuggaus-osasysteemin ja muiden osasysteemeiden välisestä kommunikoinnista. Tiedostossa ohjaus.cpp on globaalit muuttujat acpu ja aio. Näiden arvoksi alustetaan luokan MkOhjaus konstruktorissa CPU-olion ja IO-laitteet olion osoitteet. Olioiden osoitteet haetaan kerran MkOhjaus luokan konstruktorissa sen sijaan, että niitä kysyttäisiin ko luokkien Osoite-funktioilta aina uudelleen. TlLaitteet-luokan funktiota kutsutaan ainoastaan luokasta MkOhjaus ja siellä ainoastaan funktiosta SuoritaKasky. TlLaitteet-olion osoite haetaan uudestaan jokaisen MkOhjaus-luokan SuoritaKasky-funktion suorittamisen yhteydessä, koska TlLaitteet-olio on voitu tuhota välillä ilman, että MkOhjaus-oliota on myös luotu uudelleen.
Lokiintulostus toiminto on toteutettu erittäin yksinkertaisesti. Jos käyttäjä välttämättä haluaa tulostaa koko muistin lokiin, tuloksena on erittäin nopeasti hillittömän iso tiedosto... Tiedostoon kirjottaminen on toteutettu C++:n I/O kirjastosta löytyvän ofstream luokan avulla ja esim. tiedoston luominen ja tiedostoon kirjoittamisen puskurointi on jätetty täysin em. luokan huoleksi.
Askel-breakpoint on toteutettu niin, että kun haluttu määrä käskyjä on suoritettu, ilmoitetaan breakpointista ja asetetaan automaattisesti ohjelman suoritus pysähtymään kun seuraavan kerran on suoritettu sama määrä käskyjä. Jos Askel-breakpointin haluaa pois päältä (niin että muut breakpointit voivat vielä olla päällä), on funktiolle AsetaAskelBreakpoint annettava argumentiksi nolla tai negatiivinen luku.
Data-alue asetetaan kahdella erillisellä funktiolla AsetaDataAlku ja AsetaDataLoppu, jotka kummatkin ottavat argumentikseen merkkijonon, jonka pitää esittää heksalukua. Argumenttina annettava alueen alku- tai loppuarvo lasketaan kuuluvaksi data-alueeseen. Data-alueen tarkastus menee päälle (jos breakpoint tarkastus on päällä) automaattisesti jos joko alku- tai loppuarvoksi antaa hyväksyttävän arvon (hyväksyttävä arvo on heksaluku ja sen lisäksi suurempi kuin nolla, mutta pienempi kuin muistin koko). Data-alueen tarkastuksen saa pois päältä antamalla alku- tai loppuarvoksi jonkun ei-hyväksyttävän arvon.
Postfix muotoon muuntaminen:
And operaattorilla katsotaan olevan korkeampi presedenssi kuin or operaattorilla.
-Rekisteriehto luetaan ja laitetaan heti listaan.
-Vasen sulku laitetaan pinoon.
-Kun vastaan tulee oikea sulku, sitä ei laiteta mihinkään, mutta pinosta siirretään merkkejä listaan kunnes vastaan tulee vasen sulku (joka myös poistetaan pinosta, mutta jota ei laiteta mihinkään)
-Kun vastaan tulee and tai or operaattori, pinosta poistetaan alkioita ja siirretään ne listaan, kunnes löydetään alempaa presedenssiä oleva operaattori. Sen jälkeen käsiteltävänä ollut alkio laitetaan pinoon.
Funktio Aseta käyttää apunaan luokan yksityisiä jäsenfunktioita Rekisteri ja AndOr. Kun Aseta huomaa syötejonossa merkin a (and), o (or), ( tai ), se kutsuu funktiota AndOr, joka huolehtii näiden symbolien käsittelystä.
Funktio MkRekEhdot::Tarkasta laskee luokan jäsenmuuttujassa lista olevan postfix-lausekkeen arvon seuraavasti:
Listaa lähdetään käymään alusta alkio kerrallaan. Jos alkio on tyyppiä EHTO kysytään sen arvoa, joka on joko 1 tai 0. Tämä arvo laitetaan pinoon. Jos alkio ei ole EHTO (eli se on tyyppiä MERKKI), pinosta nostetaan kaksi arvoa ja operaattoria käytetään niihin, jonka jälkeen tulos laitetaan pinoon.
Timer on 16-bittinen rekisteri (TCNT), jonka arvoa kasvatetaan joka kellojaksolla. Rekisterin ylivuoto asettaa timerin ylivuotolipun (TOF), josta tulee keskeytys (9), jos timerin ylivuotokeskeytys on sallittu (TOI asetettu). Timerissa on 5 output compare -rekisteriä ja 3 input capture -rekisteriä. Timerin arvon voi lukea, mutta siihen ei voi kirjoittaa. Output compareen kuuluu 5 16-bittistä rekisteriä (TOCn), joihin talletetaan haluttu timerin arvo, jolloin outputnastan pulssi muuttuu automaattisesti (kääntyy, ei muutu, muuttuu 0:ksi tai 1:ksi). Muutosta ohjataan 8-bittisellä rekisterillä (TCTL1). Output compare 1 voi ohjata kaikkia viittä output comparea. Rekisteri OCM1 kertoo, mihin pinneihin output compare vaikuttaa ja OC1D, mitä porttiin kirjoitetaan. Lähdöt muuttuvat, kun timerin arvo on sama kuin OC1. Jos kaksi output comparea yrittää ohjata samaa pinniä, OC1:llä on korkeampi prioriteetti ja se saa kirjoittaa pinniin. TOCn-rekisterit alustetaan resetissä arvoon FFFF. Output comparen arvon voi muuttaa odottamatta haluttua timerin arvoa kirjoittamalla rekisteriin CFORC ykkösen halutun pinnin kohdalle, jolloin tapahtuu rekisterillä TCTL1 ohjelmoitu output-toiminto. Output comparen tapahtumista tulee keskeytys, jos kyseinen keskeytyslippu on asetettu (TMSK1). Kaikilla on oma keskeytysvektori. Joka tapauksessa asetetaan lippu kertomaan tapahtumasta (TFLG1).
Pulse accumulator voi toimia kahdessa eri moodissa. Sen toimintatila riippuu PAMOD-bitistä. Kun PAMOD = 0, se laskee pulsseja input-pinnistä. Kun PAMOD = 1, se laskee kellojaksoja (taajuus E-kello/64) silloin kun input-pinnin arvo on PEDGE-bitillä määritelty. Kun PEDGE = 0, lasketaan laskevia reunoja ja kun PEDGE = 1, nousevia reunoja. Kun PEDGE = 0 ja PAMOD = 1, lasketaan kellojaksoja, kun PAI = 1 ja kun PEDGE = 0, lasketaan kellojaksoja, kun PAI = 0. Laskuri on 8-bittinen rekisteri PACNT.
AD-muunnin on 8-kanavainen ja 8-bittinen. AD-muunnin laitetaan päälle ADPU-bitillä OPTION-kontrollirekisterissä. Se ei käynnisty itsestään resetin jälkeen. RC-oskillaattorin käyttöä vaihtoehtoisena kellona AD-muuntimessa ei ole toteutettu, vaan se toimii aina E-kellon mukaan. CSEL-bitti alustetaan nollaksi ja sen muuttamisella ei simulaattorissa ole merkitystä. Muunnin tekee neljä muunnosta kerrallaan, joko neljä kertaa peräkkäin valitulta kanavalta tai yhden jokaiselta neljältä. Neljän muunnoksen sarja vie 128 E-kellojaksoa. A/D control status register (ADCTL) sisältää CCF-lipun, SCAN-lipun, MULT- lipun ja Channel select-liput. Muunnoksen jälkeen asetetaan CCF-lippu. Tähän bittiin ei voi kirjoittaa. Se alustetaan nollaksi. Joka kerta, kun ADCTL-rekisteriin kirjoitetaan, lippu nollataan ja uusi muunnos aloitetaan välittömästi. Muunnoksia voi tehdä jatkuvasti tai yhden neljän muunnoksen sarjan. Kun SCAN-lippu on 0, tehdään neljä muunnosta. Kun se on 1, tehdään jatkuvasti muunnoksia ja päivitetään tulokset muunnoksen jälkeen tulosrekistereihin. Kun MULT-lippu on 0, tehdään kaikki neljä muunnosta samalta kanavalta, joka määrätään channel select -lipuilla. Kun MULT on 1, tehdään muunnos vuorotellen neljältä kanavalta, jotka määrätään channel select -lipuilla CD ja CC. Muunnoksen jälkeen tulokset kirjoitetaan A/D-tulosrekistereihin. A/D-tulosrekisterit (ADR1-ADR4) ovat read only -rekisterejä. Ensin täytetään ADR1, sitten ADR2 jne. Jännite VL (kytketty nastaan 21) vastaa rekisterin arvoa 0 ja VH (nasta 18) arvoa FF. Siis digitaalinen arvo = floor((V-VL)/(VH-VL)*256).
Keskeytyksest tarkistetaan joka käskyn suorituksen jälkeen. IO-laitteiden aiheuttamat keskeytykset tunnistetaan vain, jos CCR-rekisterin I-bitti on 0. Keskeytysten prioriteettia voi muuttaa HPRIO-rekisterin biteillä PSEL0-PSEL3, kun CCR:n I-bitti on 1. Keskeytyksen tapahduttua kaikki CPU:n rekisterit laitetaan pinoon järjestyksessä PCL, PCH, YL, YH, XL, XH, A, B ja CCR ja haetaan PC:lle uusi arvo kyseisen keskeytyksen keskeytysvektorista. CCR:n I-bitti asetetaan ykköseksi. Sitten käsitellään keskeytys, jolla on korkein prioriteetti. CCR:n X-bittiä ei huomioida. Tämän jälkeen käsitellään muut keskeytykset järjestyksessä ennen kuin jatketaan käskyjen suoritusta.
Rekisterit, joihin manuaalin mukaan voi kirjoittaa vain 64 ensimmäisen
kellojakson aikana on simulaattorissa kokonaan kirjoitussuojattu, koska
niiden muuttamiseen ei ole tarvetta.
RAMin ja rekisterien osoitteita muistissa ei siis voi vaihtaa, vaan ne ovat
kiinteästi paikoissa
$0000 - $00ff 68hc11 internal ram $1000 - $103F 68hc11 internal registers $0000 - $7FFF 32k RAM (partially hidden) $C000 - $FFFF 16k (of 32k) EPROM.
Testaus on suoritettu osaksi prosessorin vanhaan käyttöliittymään lisätyillä I/O-laitteiden muistiosoitteiden tulostuksilla ja mahdollisuudella muuttaa näiden muistipaikkojen arvoja, ja osaksi valmiilla simulaattorilla. Tässä on käytetty samoja testiohjelmia kuin CPU:nkin testaamisessa. I/O-laitteiden eri osia on testattu erilaisilla testitulostuksilla, jotka saa päälle Makefilestä asettamalla ko. testausliput. I/O-laitteet ovat testeissä toimineet niin kuin oli tarkoituskin.
Riman testaus on suoritettu yksinkertaisella testausohjelmalla, jota käyttäjä voi ohjata ja joka lukee ja kirjoittaa riman nastoihin halutut arvot ja tulostaa riman sisällön. Rima on toiminut kaikissa testitapauksissa niin kuin oli tarkoituskin.
Auton_sijainti -funktio tekee luokassa suurimman työn eli liikuttaa autoa. Funktiossa käsitellään autoon liittyviä vektoreita kahdessa eri koordinaatistossa. Auton nopeus ja asento ilmoitetaan rataan sidotussa koordinaatistossa, jossa x-akseli on oikealle ja y-akseli ylös. Tämä siksi, että uutta auton paikkaa laskettaessa voidaan nopeusvektorin x- ja y-komponentit ajalla kerrottuna suoraan summata nykyisiin koordinaatteihin. Sitävastoin autoon kohdistuvat voimavektorit sekä niiden laskentaan tarvittavat renkaiden nopeusvektorit ovat autoon sidotussa koordinaatistossa, jonka x-akseli on auton keulaa kohti ja y-akseli vasemmalle. Funktiossa lasketaan ensin etu- ja sitten takarenkaiden ohjausvoimat, jotka aiheutuvat renkaan asennon poikkeamisesta sen oman nopeusvektorin suunnasta. Seuraavaksi näihin summataan jarrujen ja moottorin voimat. Mikäli voimavektoreiden pituus ylittää voiman, joka renkaiden kautta voidaan maksimissaan lepokitkakertoimella välittää, vektoreille lasketaan uusi pituus käyttäen liikekitkakerrointa. Kitkakertoimet on määritelty tiedostossa autodata.h. Samasta paikasta voidaan myös säätää mekaniikasta aiheutuvia kitkavoimia. Jos havaitaan, että moottorivoima on suurempi kuin mitä renkaan kautta voidaan välittää, vähennetään välittyvää voimaa vielä sutimisen vuoksi. Voimaa vähennetään logaritmisesti voimien suhteessa. Näin saatujen voimien avulla lasketaan nopeuden ja kulmanopeuden muutokset. Uusien nopeuksien avulla lasketaan auton uusi paikka ja asento. Lisäksi tehdään tarkistus siitä, heilahteleeko auto paikoillaan ohjausvoimien vaikutuksesta ja asetetaan tarvittaessa nopeus nollaksi ja lopetetaan näin turha rimpuilu. Funktion lopuksi ilmoitetaan toimilaitteille, fysiikkamallissa tapahtuneen muutoksia ja palautetaan käyttöliittymälle auton uusi paikka ja asento sekä tieto onko auto teipin lähellä. Käännösoptiolla -DFYSIIKKADATATULOSTUS voidaan fysiikkamalli laittaa tulostamaan aina kutsun päättyessä kaikki keskeiset suureensa voimista auton ja renkaiden asentoon saakka. Tulostusmuoto on kryptinen.
Auton_voimat ja Akselinopeus -funktioissa vain palautetaan kysytyt arvot. Etaisyys_teipista -funktiossa lasketaan tietyn fotodiodin tai auton massakeskipisteen etäisyys rataa kuvaavan teipin keskilinjasta. Apuna käytetään Pisteen_Etaisyys_Vektorista -funktiota. Etaisyys_teipista -funktion aluksi lasketaan fotodiodin numeron perusteella mittauspisteen paikka radalla. Mittauspisteen paikaksi otetaan fotodiodin ja sitä vastapäätä olevan ledin puolivälissä oleva piste. Se lasketaan asettamalla keulaan-vektori auton keskipisteestä kohti auton nokkaa ja summaamalla tähän sivulle-vektori, joka kulkee auton keskilinjasta mittauspisteiden riviä jommallekummalle sivulle päin. Tämän jälkeen keulaan-vektorin loppupisteestä saadaan mittapisteen sijainti. Jos funktio saa parametrinaan luvun -1, se laskee anturin mittapisteen sijasta auton keskipisteen etäisyyden teipistä. Tätä käytetään määrittämään ollaanko ulkona radalta. Rata on jaettu optimonnin takia moneen pienempään osioon. Koska auto on tietyllä ajan hetkellä ainoastaan yhdessä osiossa, riittää kun tutkitaan ainoastaan tämän osion vektorit. Funktiossa käydään lävitse rata osion kahteen suuntaan linkitetty vektorilista, kutsumalla jokaiselle vektorille funktiota Pisteen_Etaisyys_Vektorista. Tämän tuloksena muuttujaan lyhin_etäisyys saadaan mittapisteen lyhin etäisyys teipin keskilinjasta. Funktiossa Pisteen_Etaisyys_Vektorista tutkitaan ensin sijaitseeko annetun vektorin suuntaisen suoran mittapistettä lähin piste kyseisellä vektorilla. Jos näin on, niin vasta sitten muodostetaan suoran yhtälö, lasketaan pisteen etäisyys suorasta ja palautetaan se. Jos piste oli vektorin ulkopuolella, palautetaan vektorin päätepisteistä se, joka on lähempänä mittapistettä.
Sekä fysiikkamallin, että toimilaiteosan testaukseen on käytetty Makefilen käännösoptiota -DKASIOHJAUS. Tällöin näppäimillä A, S, D ja W voidaan ohjailla autolle saapuvia pulssien pituuksia ja tarkkailla fysiikkamallin ja toimilaitteiden toimintaa. Prosessoriosaa ei tällöin kutsuta lainkaan vaan sen korvaa laitteet/prosu/ -hakemiston tiedostot prosu.cpp ja prosu.h. Tarvittaessa voi Makefilesta asettaa myös sopivia ylimääräisiä tulosteita näkyväksi.
Prosessori pyöräyttää toimilaitteita kutsuessaan Keraa_tiedot -funktiota. Tällöin suoritetaan ohjausservon, moottoriservon, kulmapotentiometrin, nopeusanturin ja käynnistysnapin tilojen tutkinta. Fotodiodien toiminta suoritetaan, kun fysiikkamalli kutsuu Auto_liikahtanut -funktiota. Lisäksi luokalla on vielä seuraavat toimilaitteiden tietoja välittävät funktiot: Heijastunut_kirkkaus, Tehoprosentti, Moottorin_teho, Jarruvoima, Ohjauksen_kohdekulma ja Rengaskulma.
Aseta_sensitiivisyys (int tila);Määrää tilan mukaan sen mitkä napit ovat kulloinkin painettavissa.
Poista_work_proc (void);Pysäyttää simulaation poistamalla Work Proc funktion Suorita. Work Proc on funktio, joka suoritetaan aina kun event-jono on tyhjä (no events are pending).
Kommentteja käyttäjälle voi kirjoittaa suoraan julkiseen Widgettiin kommenttirivi (parempi tapa olisi tehdä siitä yksityinen ja määritellä julkinen funktio siihen kirjoittamiseen).
Luokka pitää muistissa scrollbarin edellisen aseman, siten on mahdollista siirtää se aina päivityksen jälkeen samaan kohtaan.
Paivita (double x, double y, double asento, Boolean luistaako);Päivittää auton paikan. Luistamistiedolla ei tehdä vielä mitään, mutta tarkoitus on tehdä rataikkunaan mustaa jälkeä silloin kun auton renkaat sutivat.
Luo_gct (void)Luo pixmappien Graphics Contextit, jotka määräävät piirtämiseen liittyviä attribuutteja.
Aseta_sensitiivisyys (int tila);Kun simulaatio on käynnissä, ei auton paikkaa voi vaihtaa. Tämä funktio muuttaa ikkunan mahdollisia toimintoja tilan mukaan.
Funktiolla Rata *Anna_rata (void), voi kysyä rataolion osoitetta.
KlAkselit *akselit; KlRenkaat *eturenkaat; KlRenkaat *takarenkaat; KlRenkaat *kohdekulmarenkaat; KlMoottori *moottori; KlAnturi *anturi[NMB_OF_DETECTORS]; KlNopeus *nopeus; KlKitka *kitka_etu; KlKitka *kitka_taka;
GC gc;Graphics contexts on X:n määrittelemä struktuuri, jossa määritellään ominaisuudet miten grafiikka primitiivit piirretään.
Koordinaatti Kierra (Koordinaatti z, Koordinaatti z_r,
double sin_kulma, double cos_kulma);
Rotaatio-operaatio. Argumenttina piste (x, y), piste (x_r, y_r)
jonka suhteen kierretään ja kulmasta valmiiksi lasketut sin ja
cos arvot (tämä tehokkuus syistä).
Paluuarvo uusi piste (x', y'). Toteutettu inline-funktiona.
Widget drawing_a;Tähän widgettiin piirretään.
Luokka määrittelee myös puhtaan virtuaalifunktion virtual void Piirra (Drawable) = 0;, joka on toteutettava jokaisessa johdetussa luokassa!
Seuraavat luokat ovat tästä kantaluokasta johdettuja luokkia.