Programování pro malé i velké – Lego RIS 2.0, základy jazyka NQC, 1. díl

Minule jsme zmiňovali možnost programovat roboty postavené ze stavebnice Lego RIS 2.0 v jazyce NQC a prostředí BricxCC. V článku použité programy jsou testované na modelu ZRP, Základním Robotu na Pásech. Postup jeho konstrukce najdete na stránkách http://www.roboti.unas.cz v sekci konstrukce robotů.

Pokud se ZRPa sestavit nepodaří, můžete klidně použít robota Roverbot, jehož konstrukce je popsaná v návodu u stavebnice. Náš ZRP vypadá takto:

Každý program v NQC musí obsahovat hlavní úlohu task main(), kterou překladač označí za výchozí bod hotového programu. Klíčové slovo task označuje, o jaký druh úlohy se jedná, identifikátor main je názvem úlohy. Syntaxe vypadá následovně:

task main()
{
  /*tady bude kód*/
}

Mezi složené závorky {} budeme psát jednotlivé příkazy, které se po spuštění úlohy main() vykonají.  Kód uzavřený mezi dvěma lomítky s hvězdičkou je poznámka, tu překladač ignoruje.

Začneme s tím nejjednodušším – s pohybem robota. Robota pohání dvojice motorů a ty chceme spustit. Příkazy pro ovládání motorů jsou: OnFwd(„motory“), OnRev(„motory“) a Off(„motory“), přičemž pomocí prvního příkazu robot rozjedeme dopředu, pomocí druhého dozadu a pomocí příkazu Off() ho zastavíme. Nezapomeňte přitom, že směr vpřed a vzad určuje polarita zapojených kontaktů. Jednotlivé příkazy musí být odděleny středníkem. Nyní si to vyzkoušíme na příkladu

task main()
{
  OnFwd(OUT_A+OUT_C);  /*OUT_A je motor na výstupu A, OUT_C je o motor na výstupu C*/
  Wait(100); /*viz dále*/
  OnRev(OUT_A+OUT_C);
  Wait(100); 
  Off(OUT_A+OUT_C);
 
}


Robot pojede jednu sekundu dopředu, poté sekundu zpátky a zastaví. V programu je použit příkaz Wait(100). Ten je velice důležitý, protože jinak by zapnutí a vypnutí motorů proběhlo téměř souběžně. Doba, po jakou nedojde k žádné úmyslné změně stavu robota, je uvedena v závorce v setinách sekundy.

Zatáčení u pásového vozidla docílíme tak, že jeden motor necháme běžet směrem dopředu a druhý dozadu. Opět nezapomeneme vložit příkaz Wait(). Motory robota nejsou krokové a chceme-li docílit otočení např. o 90°, musíme patřičnou prodlevu odhadnout a zkoušením doladit, mimo jiné i podle typu povrchu, po jakém se budou pásy pohybovat.

task main()
{
  OnFwd(OUT_A);
  OnRev(OUT_C);
  Wait(105);
  Off(OUT_A+OUT_C);
}

Pomocí příkazu SetPower(„motory“, „síla“), kde síla je číslo od 0 do 7 (sedm pro nejvyšší otáčky), lze ovlivnit výkon motorů. konkrétní případ může vypadat třeba takto:

SetPower(OUT_B,5); /* nastaví rychlost otáčení motoru na výstupu B na 5)*/

Toto je pouze základní přehled příkazů pro motory, o dalších až příště.

V programu můžeme použít proměnné, konstanty nebo náhodná čísla. Proměnné definujeme na kterémkoliv místě zdrojového textu programu příkazem int „název proměnné“ před jejich prvním použitím; například takto:

task main()
{
  int ipohyb_vpred;
  ipohyb_vpred = 100; /*takto vypadá přiřazení*/
  OnFwd(OUT_A+OUT_C);
  Wait(ipohyb_vpred); /*proměnné lze použít jako parametry příkazů*/
  Off(OUT_A+OUT_C);
}

Konstanta je identifikátor, který nahrazuje jednu konkrétní hodnotu. Konstanty se definují na začátku programu takto:

#define pohyb_rovne 150

Konstanta dostala název pohyb_rovne a zastupuje hodnotu 150. Stejně jako názvy pro čísla můžeme definovat např. názvy motorů:

#define levy_motor OUT_A /*v programu místo OUT_A stačí psát levy_motor*/

Zbývá se zmínit o náhodných číslech. Zatím jsme do proměnných přiřazovali pouze neměnné hodnoty, jazyk NQC však dovoluje pracovat i s náhodnými čísly; syntaxe je následující:

int nahoda;
nahoda = Random(100);

Proměnná nahoda bude obsahovat náhodně vybrané číslo z intervalu 0 až 100 (včetně 0 a 100); obecně příkazem x=Random(n) se do proměnné x uloží číslo od 0 do n. S náhodnými čísly může být chování robota mnohem zajímavější.

Prostou posloupnost příkazů doplníme podmíněným příkazem. Příkaz if se dá česky vyjádřit větou: „Jestliže platí podmínka, něco vykonej.“ Syntaxe vypadá následovně:

if (podmínka)
{}
else /* tato část je nepovinná */
{}

Pokud platí podmínka v závorce, vykonají se příkazy ve složených závorkách, a pokud podmínka splněna není, bude program vykonávat příkazy ve složených závorkách následujících po příkazu else. Část s else u příkazu if být nemusí, potom by se v případě nesplnění podmínky vykonával kód až za ukončovací složenou závorkou. V podmínce se vyhodnocuje pravdivost nějakého výrazu, např.:

  int i;
  i =  Random(5);
  if(i>2) /*pokud bude hodnota v i větší než 2, bude se provádět část za if*/
  {
    OnFwd(OUT_A+OUT_C);
  }
  else /*jinak se bude provádět tato část*/
  {
    OnRev(OUT_A+OUT_C);
  }

Operátory použitelné při zápisu podmínek jsou shrnuty v tabulce:

Symbol Význam
== je rovno
!= není rovno
< je menší
> je větší
<= je menší nebo rovno
>= je větší nebo rovno

V závěrečném programu necháme robota rozjet rovně a po 1,5 sekundě náhodně zatočí o 90 stupňů doleva nebo doprava. Po další sekundě znovu náhodně zatočí a poté zastaví.

task main()
{
  OnFwd(OUT_A+OUT_C);
  Wait(150);
  if (Random(1) ==  0 )
  {
    OnRev(OUT_A);
    Wait(105);
    OnFwd(OUT_A);
  }
  else
  {
    OnRev(OUT_C);
    Wait(105);
    OnFwd(OUT_C);
  }
  Wait(100);
/*------------------po prvním zatočení----------------------------*/
  if (Random(1) ==  0 )
  {
    OnRev(OUT_A);
    Wait(105);
    OnFwd(OUT_A);
  }
  else
  {
    OnRev(OUT_C);
    Wait(105);
    OnFwd(OUT_C);
  }
/*------------------po druhém zatočení----------------------------*/
  Off( OUT_A+OUT_C );
}


Příště se podíváme na cykly, využití senzorů a přehrávání hudby.

autoři: Filip Děchtěrenko, Mirek Dočekal a Jakub Sedlák

Diskuze (6) Další článek: Paroubek s ministerstvem informatiky po volbách nepočítá

Témata článku: , , , , , , , , , , , , , , , , , , ,