Követelmény leírás

Logikai felépítés

A raktár:

Végtelenül nagy kapacitású és végtelenül kicsi térbeli kiterjedésű, tehát a robotok mindig azonos utat tesznek meg a felvevő- és a lerakóhely között. A szállítórobotok sebessége azonos, egy szállítmány elpakolásához 1 órára van szükségük.

Robotok:

A rakodó robotokat elektromos áram hajtja, az energiát nagy kapacitású akkumulátorokból nyerik. Fixen telepített töltőrobotok látják el árammal a lemerült egységeket. Ha egy szállítórobot töltöttsége 10% alá esik, akkor már nem vesz fel újabb rakományt, hanem a depóba megy és ha van szabad töltőrobot, akkor rákapcsolódik, ha nincs akkor leparkol amíg fel nem szabadul egy.

Robot típusok:

  • MovR: Szállító robot. Több féle verzió is létezhet belőle, előre lehet definiálni ezeket egy fájlban, amit a program beolvas. Megadható az ár, teherbírás, egy töltéssel elszállítható áru mennyisége.
  • PowR: Ezen egység(ek) feladata a szállítást végző robotok feltöltése. Egy PowR egység egyszerre egy robotot tud tölteni. Ára 9000€.

Az áru:

Nincs térbeli kiterjedése és darabszáma, csak tömege. Mikor beérkezik bizonyos mennyiségű áru, a program ennek tömegét hozzáadja a már várakozó mennyiséghez. A szállítórobotok mindig maximálisan feltöltődnek rakománnyal, ha a sorban álló áru tömege meghaladja a robot kapacitását. A csomagok tömegét és érkezési idejét fájlban lehet tárolni, amit a felhasználó táplálhat be a programba a futtatás elején.

Minőségi mutatók

A program nem fagyhat le attól, ha a felhasználó hibás karaktereket ad meg a konzolablakban, viszont a beolvasott fájlokról feltételezzük, hogy hibátlanok, illetve ha hibás adatot talál a program, akkor hibaüzenetet követően kilép.

Felhasználói esetek

A felhasználóval konzolablakon keresztül kommunikál a program, előre definiált lehetőségek közül kell választani egy menürendszeren keresztül. A robotok tulajdonságait automatikusan tölti be a program egy fájlból, míg a szállítmányok méretét és ütemezését a felhasználó adhatja meg egy szöveges fájl formájában.

image

Mérföldkövek

  1. Követelményleírás készítése
    • Feladat: Program alapvető felépítésének meghatározása, programozási platform, paradigma kiválasztása, felhasználói esetek számbavétele.
    • Munkaidő: 15 munkaóra
    • Határidő: 2012.10.17.
  2. Objektumok megtervezése
    • Feladat: Modulok, objektumok megtervezése OOP szemléletben Visual Studio 2012 segítségével.
    • Eredmény: Absztrakt modell, mely alapján neki lehet állni a kódolásnak is.
    • Határidő: 2012.11.01.
  3. Felhasználói felület megtervezése
    • Feladat: Menürendszer kialakítása, felhasználói esetek véglegesítése.
    • Határidő: 2012.12.01.
  4. Műveletek implementációja
    • Feladat: Az objektumok közötti interakció megvalósítása a már rögzített eseteknek megfelelően.
    • Határidő: 2012.12.20
    • Idáig nagyjából tartva volt az ütemterv.
  5. Tesztelés, utolsó simítások
    • Végső határidő: 2013.01.16. helyett 01.23.
    • +1 hét munka szükséges még nagyjából.

Költségek

Ötös Szoftvertechnológiából. :)

Időbefektetés

01.23-ig nagyjából 50 óra.

Rendszerterv

A program felépítése

A programot részegységekre tagoljuk az osztályok mentén.
A menün keresztül végezzük a főbb műveleteket. A felhasználónak lehetősége van elindítani a szimulációt azzal, hogy a következő napra lép (addig teheti ezt meg, amíg az adatforrásban találunk következő napi sort), robotokat vásárolni, illetve a robotok működését szabályozni (működés szüneteltetése, újraindítás). Van még egy kiíró művelet, amivel a választható lehetőségeket tudjuk kiírni a felhasználónak. Egy vektoron keresztül lehet paraméterezni, a választott menüpont sorszáma lesz a visszaadott érték.
Szükségünk van 2 különböző robot típusra. Ezek közös attribútumai az azonosító, ár, állapot, felszabadulási időpont (meddig töltődik, illetve tölt a robot).  A robotokat a Warehouse térkép objektumaiban tároljuk. Egyedi kulcsként a Robot objektumok azonosítóját használjuk és a foglaltság szerint vannak rendezve (ez még nem tudom hogyan lesz megoldva).
A program működésének központja a raktár: Ha a menüben meghívódott a NextDay() művelet, akkor az megnézi az Items() művelettel, hogy van-e a sorban elraktározatlan elem az adott napra. Ha talált, akkor keres egy szabad szállítórobotot és az elem átkerül az elraktározott elemek közé. Ha nem fél fel egészben a robotra, akkor több részletben is el lehet szállítani a rakományt. Ha lemerült, akkor az utolsó elszállított rakomány beérkezésének idejéhez hozzáadva fél órát, plusz a töltéshez szükséges időt megkapjuk az időpontot, amikortól a robot újra munkára kész. Ha nincs éppen szabad töltőrobot, akkor a legkorábban felszabaduló töltőhöz beáll a robotunk. Úgy kapjuk meg a felszabadulás idejét, hogy a töltő még hátralevő foglalt idejét hozzáadjuk az alap töltési időhöz.
Ha nincs több rakomány a sorban az adott napra, akkor a menü kiírja az adott napon elszállított áru mennyiségét, illetve ennek költségét. A költségeket a NewOutlay() műveleten keresztül adminisztrálhatják a különböző objektumok az adott napra.

Osztálydiagram

A program felépítése megpróbálja a valóságot modellezni. Egyszerűbb megoldás lenne, ha a robot például csak egy logikai változót állítgatna a raktár elemein, ehelyett “átviszi” az átmeneti tárolóból az “igazi” raktárba.

Menu

Ebben az objektumban van adattagként a raktár és a naponkénti eredményeket tartalmazó tároló. A felhasználói felület is itt valósul meg a Standings() és a Show() függvények segítségével. Előbbi értelem szerűen kiírja az aktuális állapotot, utóbbi pedig paraméterként kapott választási lehetőségeket ír ki és a felhasználó válaszával tér vissza. A NextDay() függvény lépteti a szimulációt a következő napra azzal, hogy meghívja a raktár Store() eljárását.

Warehouse

A robotok, az eltárolt, illetve a még nem elszállított rakományok konténerei ennek az objektumnak az adattagjai. A Store() függvény ad utasítást egy épp szabad és nem lemerült robotnak a szállításra, amíg az adott napra van elszállítható áru.

Robot

A töltő és a szállítórobotok ősosztálya. Minden robot közös tulajdonsága az, hogy van állapotuk, áruk, és azonosítójuk. Ezekhez kapcsolódnak lekérdező eljárások is.

MovR

A Robot ősosztályból származtatott típus. Az Item típusú rakományokat tudja (akár több részletben) “átvinni” a raktár átmeneti részéből a végleges helyre, illetve ha lemerült, vár egy felszabaduló töltő robotra és feltöltődik.

PowR

Egy MovR hívhatja meg a UseUntil() eljárást, ami után a megadott ideig foglalt lesz.

Item

Egy szállítmánynak van beérkezési ideje, illetve számon van tartva, hogy mekkora része lett már elszállítva és mennyi vár szállításra. A MovR objektumok a Grab() eljárással tudják elszállítani a csomag megadott részét.

Day

Minden nap eltároljuk az aznapi költségeket, amibe beleszámít a robotok bekerülési költsége, illetve a töltések költsége is. Az Outlay() függvény meghívásával növelhetőek az aznapi költségek, ez a robotok inicializálásakor hívódik meg a Robot ősosztály konstruktorában, illetve töltéskor a szállítórobot hívja meg.

image

A program működése

Minden az adatok betöltésével kezdődik. A szállító robotok típusait és a beérkező szállítmányokat tartalmazó fájlt is a felhasználó adja meg, ezek alapján megy végbe a szimuláció.

Ha a betöltés sikeres létrejön a raktár a szállítmányokkal. Az ezután következő rész ciklikusan ismétlődik addig amíg nincs elraktározva minden csomag. Minden nap lehetőség van új robotok vásárlására, illetve a meglévő szállítórobotok leállítására, üzembe helyezésére. A szimuláció léptetésével a robotok amíg találnak elszállítható csomagot, folytatják a munkát, illetve ha lemerülnek, keresnek egy üres töltőrobotot és a feltöltődést követően újra munkába állnak.

A napok végén összesítés készül az adott napi, illetve az addigi összes szállításról. Ez a Day objektumok alapján készül, melyekbe a robotok bekerülési ára, illetve a töltések költsége íródik be.

Szekvencia diagram

image

Fontosabb állapot átmenetek

image

Adatkezelés

A program működéséhez két szöveges fájlra van szükség. Az egyikben a szállítórobot-típusok, a másikban a szállítmányok vannak.

  • movrs.dat: <ár>;<kapacitás>;<hatótáv>
  • cargos.dat: <időpont>;<súly>

Példa

2000; 50; 500
5000; 125; 1500
7500; 200; 800
[…]

2013.01.01 06:00; 30
2013.01.01 07:30; 75
2013.01.01 13:25; 114
[…]

Implementáció

A fejlesztés C++ nyelven történik objektum orientált paradigmával, melyhez Microsoft Visual Studio 2012 fejlesztőkörnyezetet használunk. A program futtatásához (legalább) 32 bites Windowst futtató PC-re van szükség.

Karbantartás

Az egész projekt Visual Studio 2012-ben készül, így egy helyen végezhető bármilyen módosítás, illetve a verziókezelés is megoldott értelemszerűen. A Source Code fülre kattintva elérhető az összes forrásállomány, beleértve a modelleket is.

Módosítások a tervhez képest

Alapvető logika

Az eredeti tervben a robotok paraméterként megkapták volna a csomagokat és azokat “bevitték” volna a raktárba. Közben kiderült, hogy ennek nem sok értelme van, egyszerűbb külön kívülről állítgatni az adattagjaikat.
Mivel többféle szállítórobot létezik (többféle kapacitással, hatótávval), ezért jobban végiggondolva nagyon nem mindegy, hogy melyik csomaghoz melyik robotot rendeljük hozzá. Ehhez szükség lesz egy olyan feltételes minimum keresésre a szállítórobotok között, ami keres egy olyan szabad robotot, aminek az aktuális kapacitása a legkisebb mértékben nagyobb az elszállítandó áru tömegénél. Ha ilyen nincs, akkor simán keresünk egy szabad robotot. Ha ilyen sincs, akkor léptetni kell az aktuális időt a leghamarabb feltöltődő robot idejére. Fejlesztés alatt!

Hamar felmerült az a kérdés, hogy az idő, illetve a különböző mértékegységek kezelése hogyan legyen megoldva. Gyorsan bele lehet zavarodni, ha mindent az alap típusokkal próbálunk leírni, így szükség volt saját típusokra a mértékegységek ábrázolásához. Utólag belegondolva lehet, hogy elég lett volna typedef-et használni pl. a Kg-nál.

TimeStamp típus

Az idő méréséhez mindenképp szükség volt egy új típusra. Az összehasonlításokhoz meg kellett írni az a logikai operátorokat, illetve a töltési idő kiszámításához szükség volt az óra léptetésére.image Mikor lefut egy beolvasás, vagy konstruktor hívás történik, meghívódik az Assign() eljárás, ami leellenőrzi, hogy helyes dátum lett-e megadva (pl., hogy az adott hónap mennyi napból áll, az adott év szökőév-e, stb.).

A StepByHours() eljárás egy integerként kapott értékkel megnöveli a hour adattag értékét. Ha ez így több, mint 24 óra, akkora a napot is léptetni kell és így tovább. Fejlesztés alatt!

Si típusok

A value adattag egy double típusú változó. Csak pozitív értéket tartalmazhat, ezt az Assign() eljárás ellenőrzi. Végül a Kg lett csak felhasználva, távolságmérésre nincs szükség.

image

Pénznem típus

Fejlesztés alatt!

Entry típusok

Az eredeti tervben Day néven szerepelt, de abban a formában nem lett volna túl informatív a felhasználónak, ezért kétféle log entry lehetséges, az egyik robot vásárlásakor, a másik szállításkor jön létre és külön-külön vektorban tároljuk a bejegyzéseket (polimorfizmus még szóba jöhet) a Menu() objektumban.

Hibakezelés

Az egyes objektumok, melyek előre láthatóan hibásan működhetnek, rendelkeznek egy Exceptions nevű felsorolt típussal. Ha hiba történik, akkor ezt az objektum tagfüggvény-hívásánál, vagy feljebbi szinten el lehet kapni. Az elsődleges logika az, hogyha a beolvasandó fájlokban van hiba, akkor hibaüzenet után kilép a program, ha viszont a billentyűzetről érkezik helytelen bevitel, akkor a főmenübe tér vissza hibaüzenet után.

Főmenü

Egy hátultesztelős ciklusba ágyazott többágú elágazásként (Options felsorolt típus vezérli) van megvalósítva.  Legalább egyszer lefut és egészen addig ismétlődik, amíg van elszállítható csomag, illetve nem lép ki a felhasználó.

Tesztelés

Be lett építve minden funkcionalitás, tesztelési terv kidolgozás alatt. A program egyelőre hemzseg a hibáktól.

Last edited Jan 23, 2013 at 7:07 AM by cereal190, version 37

Comments

No comments yet.