Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Tilakonekaaviot (state chart, state machine diagram) voi piirtää esim https://www.draw.io/ tai omalle koneelle asennettavalla Astahilla http://astah.net/download. Jälkimmäisen professional-versio on ilmeisesti ilmainen opiskelijoille mutta myös kaikille ilmainen Astah Community toimii.

  1.  1. Mallinna liikennevalot UML-tilakonekaaviona esim käyttäen kaavionpiirto-ohjelmaa. Voit olettaa, että tilakoneeseen tulee tapahtuma "30 sekuntia kulunut"  jolloin valoja voi vaihtaa. Voit halutessasi mallintaa myös liikennevalojen välitilat joissa keltainen valo on päällä. http://en.wikipedia.org/wiki/UML_state_machine
  2.  2. Toteuta tilakoneesi tehtävästä 1 switch-case rakenteella. Voit käyttää koodin kirjoittamiseen esimerkiksi http://ideone.com/ -ympäristöä. Kieleksi voi valita esim. C++11
    Esimerkki tällä tavalla toteutetusta tilakoneesta löytyy sivulta Yksinkertainen Caps Lock -tilakonemalli tai osoitteesta http://en.wikipedia.org/wiki/Event-driven_finite-state_machine
  3.  3. Tee Qt Creatorissa uusi käyttöliittymäsovellus. Muunna tehtävän 2 tilakone Qt-sovellukseksi.
    - Kopioi C++-sovelluksesi tapahtumankäsittelijäfunktio mainwindow.cpp:hen MainWindown alaiseksi funktioksi.
    - Kopioi enum-määrittelysi (tilat ja tapahtumat) mainwindow.h -tiedostoon ennen class MainWindow : public QMainWindow riviä eli varsinaisen luokkamäärittelyn ulkopuolelle
    - Lisää käyttöliittymään textbrowser-ikkuna ja tulosta tilakoneen tulosteet seuraavalla addText -funktiolla cout-käskyjen sijaan. (Lisää allaoleva funktio omaan sovellukseesi, lisää funktion esittely .h -tiedostoon,  ja mukauta tarvittaessa textBrowser-elementin nimi, jos olet muuttanut sitä)

    void MainWindow::addText(QString text) {
     QString currentText=ui->textBrowser->toPlainText();
     QString newText=currentText+"\n"+text;
     ui->textBrowser->setText(newText);

    }
    - Kopioi vanhan main-funktiosi sisältö MainWindow::MainWindow(QWidget *parent) -konstruktoriin.

  4.  4. Lisää tehtävän 3 tilakoneeseesi QTimer-ajastin joka kutsuu ("tikkaa") tilakonetta säännöllisin väliajoin, esim. sekunnin välein. ks. QTimerillä toimiva Caps Lock -esimerkki. Tapahtumia on mahdollista käsitellä joka kerralla, kun tapahtumankäsittelijä käynnistyy, mikäli tapahtuma-jäsenmuuttujaan on asetettu tapahtuma.
    QTimerin käyttö edellyttää muutoksia ohjelmaan:

    - QTimer-olio lähettää signaaleja, joilla ei ole parametreja. Tämän takia tilakoneen nykyinen tila pitää välittää tapahtumankäsittelijälle toisella tapaa: Esittele tilakoneen tilaa ilmaiseva muuttuja, entisen main-funktion sijaan, mainwindow.h:ssa luokan jäsenmuuttujana. (Caps Lock -esimerkissä CapsState -tyyppinen muuttuja) Tällöin se on saatavilla kaikille luokan funktioille, ja sen arvo säilyy koko ohjelman suorituksen ajan.

    - QTimer osaa kutsua vain slot-funktioita, joten lisää mainwindow.h:hon private slots: otsikko, ja siirrä tapahtumankäsittelijän esittely sinne.

    - Myös tapahtumat välitetään tässä mallissa tilakoneelle jäsenmuuttujan avulla. (Caps Lock -esimerkissä Event-tyyppinen muuttuja)

    - Lisää enumeraatioon, jossa mahdollisten tapahtumien valikoima on määritelty, erityinen NO_EVENT -arvo, ja tilakoneeseesi tälle tapahtumalle käsittelijä, joka ei tee mitään.

    - Lisää tilakoneesi kaikkien muiden tapahtumien käsittelyihin tapahtuma-jäsenmuuttujan nollaaminen NO_EVENT -arvoon.

    - Tee MainWindow-luokan konstruktorissa/rakentimessa QTimer-olio, joka kutsuu kasitteleTapatuma()-slotia sekunnin välein

    - Nyt voit muuttaa tilakoneen tilaa muuttamalla tapahtuma-jäsenmuuttujan arvoa ohjelman ollessa käynnissä.
    Lisää jokaista tapahtumaasi kohti yksi tapahtumanlaukaisijafunktio (slot) mainwindow.cpp:hen (ja sen esittely mainwindow.h:hon private slots: otsikon alle). Nimeä funktio kunkin tapahtuman mukaan:

    void MainWindow::keyApressed(){
        currentEvent=KEY_A_PRESSED;
    }

    Voit tämän jälkeen muuttaa tilaa esimerkiksi ajastamalla QTimer::singleShot -funktion kutsumaan ylläolevanlaista funktiota (slotia)
     QTimer::singleShot(3000,this,SLOT(keyApressed()));

    Kutsu kaikkia tapahtumanlaukaisijoitasi ajastetusti MainWindow::MainWindow-konstruktorista singleShot-kutsujen avulla. Huomaa, että singleShot laukeaa millisekunteina sen kutsumahetkestä, eli seuraava laukaisee tapthtumanlaukaisijoita sekunneilla 3,4,5,6 ja 7 koko sovelluksen käynnistyksestä:

     QTimer::singleShot(3000,this,SLOT(keyApressed()));
     QTimer::singleShot(4000,this,SLOT(capsLockPressed()));
     QTimer::singleShot(5000,this,SLOT(keyApressed()));
     QTimer::singleShot(6000,this,SLOT(capsLockPressed()));
     QTimer::singleShot(7000,this,SLOT(keyApressed()));


    Vaihtoehtoisesti voit toki lisätä sovellukseen jokaista tapahtumaa kohti painikkeita, joilla käyttäjä voi vapaasti laukoa tapahtumia silloin, kun haluaa. (Kytke tällöin painikkeiden clicked-signaalit omiin tapahtumanlaukaisijafunktioihisi, singleShotin käyttämisen sijaan.)



  5.  5. Mallinna kerrostalon hissi UML-tilakonekaaviona esim käyttäen kaavionpiirto-ohjelmaa. Sisällytä toiminnallisuuteen ainakin perustoiminnallisuus eli esim. kaikkien kerrosten painikkeet ja näytöt, jotka kertovat hissin tilasta.

 

  1.  6. (Valinnainen lisätehtävä) Lisää tilakoneeseen hissitilakoneeseen myös ovien sensorit ja ajastin oven sulkeutumiselle, sekä mahdollisuus painaa useamman kerroksen painikkeita siten, että hissi muistaa mennä niihin kaikkiin yksi kerrallaan.

  2.  7. Toteuta tilakone hissitilakone switch-case rakenteella.
    Esimerkki tällä tavalla toteutetusta tilakoneesta löytyy sivulta Yksinkertainen Caps Lock -tilakonemalli tai osoitteesta http://en.wikipedia.org/wiki/Event-driven_finite-state_machine
  3.  8. Tee Qt Creatorissa uusi ajastettu käyttöliittymäsovellus, joka simuloi hissin toimintaa. Lisää käyttöliittymään (Qt:ssa Forms:in alla mainwindow.ui tai dialog.ui) painikkeina kaikki tilakoneen tapahtumat, esim. kaikkien kerrosten nappula, ja jos tilakoneessasi voi nappia painaa myös hissin sisällä, lisää myös nämä nappulat. Lisää tämän lisäksi tekstikenttä kuten tehtävässä 4, joka näyttää tilakoneen tilan jokaisella hetkellä.
  4.  9. Toteuta aikaisemman tehtävän liikennevalot Qt:n QStateMachine:na. Esimerkki Qt:n tilakoneen käytöstä löytyy sivulta Erittäin yksinkertaiset liikennevalot Qt-tilakoneena. Kytke esimerkkiin QTimer-ajastin, joka pyörittää liikennevaloja painikkeen sijaan.
  5.  10. Toteuta aikaisemman tehtävän hissi Qt:n QStateMachine:na.
  6.  11. Toteuta Qt:n QStateMachinella liikennevalo-tilakone, jossa on mallinnettuna sekä yksittäisen liikennevalon, että koko risteyksen tilanne. Tarvitset tähän alitilakoneita.

...