Domácí úkol č. 1: Dekódovanie signálu

  • Úkol zadán: 29. 9. 2015
  • Odevzdávání naostro možné od: 30. 9. 2015
  • Absolutní konec odevzdávání: 13. 10. 2015 6.00 (slovy šest hodin ráno)
  • Odevzdáváte soubory: coder.h, codermanchester.cpp, codermanchester.h, codernrzi.cpp, codernrzi.h, coderrz.cpp, coderrz.h

Doplnění zadání (zobrazeno podtrženě):

  • poznámka o formáte vstupu v bonuse č. 2 (a teda aj v referenčnej binárke)
  • pridaná binárka na testovanie návratových hodnôt funkcií
  • doplnená priorita návratových hodnôť

Představení úkolu

Prenos digitálneho signálu zohráva v súčasnosnom svete dôležitú úlohu. Pre zabezpečenie bezchybnosti prenosu a synchronizácie zariadení nie je možné signál posielať priamo, dochádza k jeho dekódovaniu. V tejto úlohe sa zameriame na dekódovanie a kódovanie jednoduchých kódovaní Manchester, Return to Zero (RZ) a Non Return to Zero - Inverted (NRZ-I).

Zadání

Vašou úlohou bude vytvoriť pre každé z vyššie uvedených kódovaní samostatnú triedu, ktorá bude kódovať a dekódovať signál príslušným kódovaním. Triedy budú implementovať rozhranie (abstraktnú triedu) dodanú v hlavičkovom súbore coder.h dostupnom tu: coder.zip. Inštancie tried budú tiež schopné overiť, či je možné daný signál korektne dekódovať.

Signál je reprezentovaný reťazcom, pričom rozoznávame tri úrovne signálu: kladnú amplitúdu, zápornú amplitúdu a nulový signál (kódovanie nemusí využívať všetky úrovne). Jeden znak reťazca zodpovedá úrovni signálu počas jednotky času.

Pri vytvorení inštancie triedy bude možné zvoliť symboly, pomocou ktorých bude signál zapísaný. Okrem toho bude trieda obsahovať metódu, ktorá vráti celkový počet výstupných znakov úspešne dekódovaných/zakódovaných danou inštanciou.

Požadavky

  • Program bude obsahovať triedy CoderManchester, CoderRZ a CoderNRZI, ktoré budú implementovať rozhranie triedy Coder.
    • ich deklarácie sa budú nachádzať v súboroch coderX.h (X označuje názov kódovania: napr. CoderRZ bude deklarovaný v súbore coderrz.h) spolu s deklaráciami členských metód a ich vhodnou dokumentáciou.
    • definície metód budú umiestnené v súbore coderX.cpp.
    • každá z tried bude implementovať verejné metódy decode, encode, getLastTranslatedLength a dva verejné konštruktory.
    • triedy nesmú obsahovať žiadne ďalšie verejné metódy a atribúty (s prípadnou výnimkou deštruktoru), môžu však obsahovať ľubovoľný počet privátnych metód a atribútov.
Vopred dodané rozhranie nemodifikujte!
  • Funkcie encode a decode budú využívať výčtový typ ErrorCode, ktorý si vytvoríte v súbore coder.h.
  • Hodnoty výčtového typu sú nasledovné:
    • OK - vstup bol úspešne zakódovaný/dekódovaný
    • INVALID_CHARACTER - vstup obsahuje neznámy znak
    • INVALID_FORMAT - vstup obsahuje postupnosť znakov, ktorá nie je daným kódovaním dekódovateľná
    • INVALID_CHARACTER_SET - v prípade akejkoľvek kódovacej operácie v prípade, že sa zhodujú dva symboly zadané parametrickému konštruktoru
  • Pri vyhodnocovaní správnosti vstupu má INVALID_CHARACTER vyššiu prioritu ako INVALID_FORMAT (teda ak sa vo vstupe nachádza nesprávny znak, nemusíte testovať formát signálu).
Deklaráciou oznamujeme kompilátoru meno premennej alebo funkcie. V definícii funkcie je na rozdiel od deklarácie už aj samotný kód funkcie. Viac o deklaráciách vs. definíciách.

Metódy tried

  • konštruktor CoderX() (X je Manchester, RZ alebo NRZI)
    • pre interpretáciu signálu sa použijú predvolené symboly: symbol + pre kladnú amplitúdu, symbol - pre zápornú a symbol 0 (nula) pre nulový signál.
  • konštruktor CoderX(char positive, char negative, char zero) (X je Manchester, RZ alebo NRZI)
    • pre interpretáciu signálu sa použijú zadané symboly: pre kladnú amplitúdu symbol positive, pre zápornú negative, pre nulový signál symbol zero
    • v základnej verzii môžete predpokladať, že zadané symboly sú navzájom rôzne
  • size_t getLastTranslatedLength()
    • vráti počet výstupných znakov poslednej operácie (zakódovania/dekódovania).
    • prípad, že operácia skončila neúspešne nie je ošetrený (a teda nebude testovaný).
  • ErrorCode decode(const std::string& input, std::string& output)
    • skontroluje, či je možné reťazec input dekódovať (teda či sa skladá len zo správnych znakov).
    • dekóduje vstupný reťazec input podľa príslušného kódovania do výstupného reťazca output.
    • návratovou hodnotou funkcie je ErrorCode.
    • Príklad RZ: pre decode(„+0+0“, output) sa output = „11“.
  • ErrorCode encode(const std::string& input, std::string& output)
    • skontroluje, či je možné reťazec input zakódovať (teda či sa skladá len zo znakov 1 a 0).
    • zakóduje vstupný reťazec input podľa príslušného kódovania do výstupného reťazca output.
    • návratovou hodnotou funkcie je ErrorCode.
    • v prípade NRZ-I bude prvým znakom výstupu vždy 0.
    • Príklad RZ: pre encode(„101“, output) sa output = „+000+0“.
  • Môžete predpokladať, že po zavolaní decode a encode už nebudeme potrebovať výsledok predchádzajúceho dekódovania.
  • Pre otestovanie funkcionality si môžete vytvoriť vlastný main.cpp (ktorý neodovzdávate).

Popis jednotlivých kódovaní a príklady

  • v príkladoch sú pre označenie kladnej/zápornej amplitúdy a nulového signálu použité predvolené symboly (+ pre kladnú, - pre zápornú amplitúdu a 0 pre nulový signál). Napríklad signál na nasledovnom obrázku by bol reprezentovaný reťazcom 0++0-+-
  • kódovanie Manchester
    • binárna číslica 1 je kódovaná zápornou amplitúdou, ktorá stúpne na kladnú (tzn. reťazec -+), číslica 0 je naopak kódovaná kladnou amplitúdou, ktorá klesne na zápornú (tzn. reťazec +-)
    • Príklad: vstupný reťazec +--+ sa dekóduje ako 01, reťazec -+-+ sa dekóduje na 11, reťazec +-+--+ ako 001, reťazce +-- a ++ nie sú korektné
  • kódovanie RZ
    • binárna číslica 1 je kódovaná kladnou amplitúdou, ktorá klesne na nulový signál (tzn. reťazec +0), číslica 0 je kódovaná nulovým signálom po celú dobu (reťazec 00)
    • Príklad: reťazec +000+0 sa dekóduje na 101, +0+0 sa dekóduje na 11, reťazce +000+, +000++ a 0+ nie sú korektné
  • kódovanie NRZ-I
    • binárna číslica 0 je kódovaná rovnakým signálom, aký sa použil pre kódovanie predchádzajúcej číslice, číslica 1 je kódovaná zmenou signálu: ak bol signál v predchádzajúcom cykle nulový, použije sa kladná amplitúda, ak bola v predchádzajúcom cykle použitá kladná amplitúda, použije sa nulový signál (záporná amplitúda sa nevyužíva)
    • prvý znak vstupného reťazca označuje počiatočnú hodnotu signálu pred začiatkom prenosu
    • Príklad: reťazce 0000 a ++++ sa dekódujú na 000, reťazce 0+0+ a +0+0 sa dekódujú na 111, reťazec +00+ sa dekóduje na 101, reťazec +0+ sa dekóduje na 11,reťazec +--+ nie je korektný
    • Dekódovanie reťazcov + a 0 nemusíte riešiť.
  • Prípadné nejasnosti si overte vo vzorovom demo programe.
Ďalšie informácie k použitým kódovaniam nájdete napr. na http://www.rhyshaden.com/encoding.htm

1. Bonus [1b]

  • Upravte parametrické konštruktory tried (a ďalšie s tým súvisiace metódy) pre ošetrenie prípadu, že niektoré zadané symboly sa zhodovali:
    • V prípade, že sa zhodujú dva symboly, z ktorých sa ale jeden pri príslušnom kódovaní nepoužíva, sa funkcionalita nemení.
    • V prípade, že sa zhodujú dva symboly a oba sa v príslušnom kódovaní používajú:
      • vypíše konštruktor vhodnú hlášku na štandardný chybový výstup ( cerr << "hláška" << endl;).
      • kontr bude kontrolovať počet riadkov na chybovom výstupe, nevypisujte preto na chybový výstup žiadne ďalšie hlášky.
      • pri každom pokuse o dekódovanie bude vrátená hodnota INVALID_CHARACTER_SET.

2. Bonus [1b]

  • Spolu s vašim zadaním odovzdajte súbor main.cpp, na ktorom si môžete vyskúšať fungovanie vašich kódovaní.
  • Bude obsahovať nasledujúcu funkcionalitu:
    • Načíta od užívateľa ľubovoľný vstup (Reťazec zapísaný vo formáte daného signálu).
    • Vypíše či sa dá daný vstup dekódovať vo všetkých kódovaniach:
      • Ak áno, vypíše riadok <názov kódovania>: \t<dekódovaná správa> [<počet dekódovaných znakov>].
      • Ak nie, vypíše riadok <názov kódovania>: \tnie je mozne dekodovat.
    • Tu bude nasledovať prázdny riadok
    • Vypíše spetne zakódovaný text vo všetkých kódovaniach:
      • V prípade, že pôvodný text nebol dekódovateľný v danok kódovaní vypíše: <názov kódovania>: \tnie je mozne zakodovat.
      • V opačnom prípade vypíše výstup vo formáte: <názov kódovania>: \t<zakódovaná správa> [<počet zakódovaných znakov>]
    • Tu budú nasledovať 2 prázdne riadky.
    • Kódovania budú vypisované v poradí: Manchester, RZ, NRZ-I.
    • Presný formát výstupu je dostupný vo vzorovej binárke.
    • Program bude pracovať s predvolenými (výchozími) hodnotami signálu.
    • Program bude pracovať až kým nebude na štandardný vstup zadané písmeno q.
    • Príklad výstupu pre vstup „+--++--++--+“:
      Manchester:     010101 [6]
      RZ:     nie je mozne dekodovat
      NRZ-I:  nie je mozne dekodovat
      
      Manchester:     +--++--++--+ [12]
      RZ:     nie je mozne zakodovat
      NRZ-I:  nie je mozne zakodovat
      
      

Poznámky

  • Váš kód prekladajte na aise ako g++ -std=c++11 -Wall -Wextra -o signals main.cpp codermanchester.cpp codernrzi.cpp coderrz.cpp
  • V prípade nejasností máte k dispozícii vzorový demo program na aise: /home/xdaxner/pb161/hw01/signals. Tento program pracuje s mainom, ktorý je súčasťou bonusu č. 2.
  • Návratové hodnoty funkcií si môžete vyskúšať na binárke: /home/xdaxner/pb161/hw01/values, v binárke je opäť postupnosť decode - encode.
  • Ak váš kód dynamicky alokuje pamäť, ste zodpovední za jej uvoľnenie. Úlohu je však možné riešiť aj bez použitia dynamickej alokácie.
  • Súčasťou testov je kontrola Valgrindom.
  • Testy sú na sebe závislé, teda ak vám neprejde prvý test na RZ, automaticky vám neprejdu ani ostatné.
  • Pri testoch sa kombinujú vaše súbory so súbormi referenčnej implementácie, preto je nutné aby ste dodržali verejné rozhrania.
  • Vo svojej implementácií vkladajte „using namespace“ len do .cpp súborov.

Autor: Úlohu vymyslel Marek Klučár, prerobila Desana Daxnerová. V prípade nejasností kontaktujte Desanu Daxnerovú na 410301@fi.muni.cz alebo v diskusnom fóre.

QR Code
QR Code public:pb161_fall15_hw01 (generated for current page)