Programové řízení (struktura, syntax a využití) • podmínky, • cykly (s podmínkou na začátku, s podmínkou na konci, s pevným počtem průchodů), • čekání na dokončení úloh, • zastavení programu.
S rozvojem programování se ukázalo jako nezbytné mít možnost upravit chování programu za jeho běhu tak, aby se některé jeho části za určité podmínky vykonaly či přeskočily. Vznikly proto podmíněné příkazy, které před spuštěním určité části programu nejprve otestují, zda byla či nebyla splněna podmínka pro jeho spuštění.
Pro vykonání opakujících se částí naopak vznikly cykly. Ty jsou různého druhu a umožňují nám opakování buďto podle předem jasně daného počtu opakování či podle splnění či nesplnění určité podmínky. Více se o cyklech dočtete ve stejnojmenné kapitole.
Díky podmíněným příkazům a cyklům tedy můžeme například vytvořit program pro řízení světelné křižovatky, který nám pomocí cyklů opakovaně střídá signály na semaforech a díky podmíněným příkazům pak umožňuje tento běh uzpůsobit aktuální dopravní situaci, např. počtu přijíždějících aut z různých směrů či stisknutí tlačítek na přechodech pro chodce.
Asi by se nám příliš nelíbilo bezpečnostní zařízení, které by každou vteřinu vyžadovalo manuální spouštění kontroly prostoru. Bezpečnostní alarm by se měl spustit a pak až do svého vypnutí samočinně opakovaně monitorovat střežený prostor.
Právě k programovému provádění opakujících se činností nám slouží cykly. A nejde jen o alarm. V cyklu můžeme opakovaně měřit překročení hodnoty senzoru, testovat, zda uživatel nestiskl tlačítko, či zda není před našim právě jedoucím robotem nějaká překážka. A příkladů by se našla celá řada. Cykly jsou zkrátka základem každého programovacího jazyka a vytvořený program si bez nich lze jen těžko představit.
V programovacích jazycích obvykle rozeznáváme tři typy cyklů:
cyklus s podmínkou na začátku,
cyklus s podmínkou na konci,
cyklus s pevným počtem průchodů.
Cyklus s podmínkou na začátku se výborně hodí na úlohy, ve kterých provádíme určitou činnost a ještě před jejím opakovaným vykonáním otestujeme, zda je splněna podmínka (přesněji podmínkový výraz) dovolující její běh.
Praktické využití: Typické využití pro tento cyklus může být testování volného prostoru před robotem při jeho pohybu. Asi bychom nechtěli, aby se náš domácí robotický vysavač rozjel a plnou silou narazil do nohy stolu a až poté testoval, zda před ním není překážka.
Cyklus s podmínkou na konci je obdobou předchozího cyklu. Činnost je však nejprve vykonána a poté až dochází k testování, zda danou činnost znovu provést.
Praktické použití: Velmi častým příkladem využitím je realizace hlavní programové smyčky, která končí splněním úkolu. Tím může být například zaparkování vozidla na parkovací místo mezi dvěma dalšími auty či pouhé stisknutí tlačítka uživatelem informující o žádosti o ukončení programu.
Cyklus s pevným počtem průchodů je využíván tam, kde známe přesný počet opakování činnosti potřebných ke zdárnému dokončení úkolu.
Praktické použití: Za příklad nám může posloužit stroj, který se potenciálně stará o balení tabletek léků (např. Paralenu) do blistrů. V každém blistru, překrytým hliníkovou fólii jsou dvě řady po pěti lécích. Stroj tedy ví, že má uchopit tabletku ze zásobníku, přesunout ji do připravené jamky v blistru a blistr následně posunout o předem jasně zadanou vzdálenost. Pokud toto zopakuje pětkrát, má tabletkami naplněnou celou řadu. Tento cyklus může být součástí dalšího cyklu, který nejprve připraví pozici pro první a následně pro druhou řadu. Pokud by se výrobce rozhodl využít nových typů maxibalení o dvaceti prášcích (4 řady po 5 prášcích), stačí pouze upravit počet průchodů druhého cyklu.
Z pohledu využití cyklů je grafické prostředí NXT-G dosti specifické. Pro realizaci cyklů zde nalezneme pouze jeden jediný blok s názvem Loop. Ten dle nastavení umožňuje provést buďto cykly s podmínkou na konci, s pevným počtem průchodů či speciální časově omezený a nekonečný cyklus, který se dá ukončit pouze blokem Stop či stisknutím šedé tlačítka na kostce NXT.
Po přetažení bloku Loop, který nalezneme v paletě Complete > Flow, do okna programu dojde ke vložení výchozího programového cyklu.
Jeho typ je nutno zvolit v parametrech bloku.
Parametry bloku
Volba typu cyklus se provádí v sekci Control a to z těchto možností:
Forever – nekonečný cyklus ukončitelný pouze koncem celého programu.
Time – časově omezený cyklus s podmínkou na konci, který testuje uplynutí času zadaného v parametru Seconds: v sekci Until:. Pro cyklus trvající půl vteřiny zde nastavíme Seconds: 0.5.
Logic – cyklus s podmínkou na konci, který o svém pokračování rozhoduje na základě logické hodnoty přivedené na rozhodovací vstup (obrázek ano/ne).
Sensor – je kombinací předchozího cyklu s výstupem senzoru. Senzor pak poskytuje informaci, zda z něj získaná hodnota splňuje námi nastavenou podmínku. Díky tomuto cyklu pak nemusíme vkládat blok senzoru a následné propojení s cyklem Logic.
Count – cyklus s pevným počtem průchodů. Počet průchodů se nastavuje v parametru Minimální počet průchodů je stanoven na 1.
U všech cyklů lze pomocí parametru Show: Counter aktivovat výstup počítadla průchodů. To můžeme použít i pro zpracování ve vnitřní části cyklu (např. pro třídičku vykonávající odlišné operace pro sudá a lichá čísla).
Cyklus s podmínkou na začátku nejprve zkoumá, zda došlo ke splnění podmínky či podmínkového výrazu. Pokud je její výsledek pravda (true), vykoná vnořený kód (blok mezi složenými závorkami). Po jeho dokončení se cyklus vrací opět k podmínce a cyklus tak probíhá neustále dokola, dokud nedojde k nesplnění podmínky - nepravda (false).
Základní zápis cyklu
Cyklus se skládá z klíčového slova while za kterým následuje podmínka uzavřená do kulatých závorek (). Za nimi se nachází blok kódu vykonávaný při jejím splnění. Blok kódu je umístěn do složených závorek {}.
//CYKLUS S PODMINKOU NA ZACATKUwhile(true)//na misto true umistnete podminku ci podminkovy vyraz{//zde umistnete kod, ktery se ma opakovane vykonavat}
Z důvodu přehlednosti programu a odstraňování potencionálních chyb Vám doporučujeme se držet výše uvedeného formátování.
Příklad možné programové konstrukce
V následující ukázce kódu vidíte řešení přiblížení robota na vzdálenost cca. 20 cm od překážky. V případě, že se překážka nachází příliš blízko, motory se nerozjedou a robot zůstane stát.
//UKAZKA - PRIBLIZENI ROBOTA K PREKAZCE (ZDI) NA 20 CM//Robot otestuje, zda se pred nim nenachazi prekazkawhile(SensorValue[Ultrazvuk1]>20){//pokud ma pred sebou volno, prekazka je dale nez 20 cm, rozjede se//motor B a C se nastavi na 75% vykonmotor[motorB]=75;motor[motorC]=75;//protoze nehrozi kolize (prekazka je daleko) a neni tak potreba prilis//casteho testovani, nechame robota jet a dalsi test udelame za 100mswait1Msec(100);}//Cyklus skoncil, jsme na miste, vypiname motorymotor[motorB]=0;motor[motorC]=0;//Tento kod je mozno opakovat dle libosti a na rozdil od podminky na konci//nebude dochazet k neustalemu nepatrnemu priblizovani robota k prekazce
Cyklus s podmínkou na konci
Cyklus s podmínkou na konci nejprve provede příkazy umístěné v jeho těle a až následně zkoumá, zda má opětovně vykonat tento blok. Je-li podmínka či podmínkový výraz cyklu splněna (výsledná hodnota pravda (true)) bude cyklus vykonáván. Při hodnotě nepravda (false) se cyklus přeruší a pokračuje se v dalším běhu programu.
Základní zápis cyklu
Cyklus se skládá z klíčového slova do za kterým se nachází blok kódu, který je v případě splnění podmínky opakovaně vykonáván. Blok je uzavřený do složených závorek {}. Po nich následuje klíčové slovo while a podmínka či podmínkový výraz uzavřená do kulatých závorek (). Cyklus je zakončen středníkem ;.
//CYKLUS S PODMINKOU NA KONCIdo{//zde umistnete kod, ktery se ma opakovane vykonavat}while(true);//na misto true umistnete podminku ci podminkovy vyraz
Příklad možné programové konstrukce
V následující ukázce kódu vidíte řešení měřiče vzdálenosti, který počítá ujetou vzdálenost podle otáček motoru jež koeficientem přepočítává na ujetou vzdálenost. Pro snazší měření je začátek i konec měření spuštěn stiskem tlačítka.
//UKAZKA MERIC VZDALENOSTI//Meric vzdalenosti pocita pocet stupnu otoceni motoru,//ktere pak prepocita na vzdalenost a zobrazi na displeji//Ke spusteni i zastaveni mereni bude vyuzito tlacitko.//MERENI ZACNE STISKEM TLACITKAdo{//specialitou je, ze v teto sekci nebude zadny kod//opakovane se tedy bude vykonavat "nic"//jen se bude testovat, zda muzeme pokracovat}while(SensorValue(dotykovySenzor)==0);//tlacitko nestisknuto//VYMAZEME POCITADLO MOTORUnMotorEncoder[MotorA]=0;wait1Msec(1000);//nyni musi uzivatel do vteriny pustit tlacitko//A OPET TESTUJEME TLACITKOdo{}while(SensorValue(dotykovySenzor)==0);//tlacitko nestisknuto//VYPOCET VZDALENOSTI - obvod kola 12 cmfloat vzdalenost =nMotorEncoder[MotorA]/360*12;nxtDisplayTextLine(4,"%f", vzdalenost);//zobrazeni vzdalenosti na displ.wait1Msec(5000);//cekam, jinak by se displej smazal
Poznámka: V rámci zjednodušení řešení úlohy se předpokládá, že uživatel vždy stisknuté tlačítko do jedné vteřiny pustí. Pro přesnější realizaci by bylo vhodné reagovat spíše na uvolnění tlačítka.
Cyklus s pevným počtem průchodů
Cyklus s pevným počtem průchodů funguje ve třech režimech. V prvním inicializačním režimu, který nastává pouze při novém vstupu do cyklu nastaví výchozí hodnotu proměnné. Tu pak bude využívat pro řízení cyklu. V druhé části dochází k porovnání zadané podmínky. Není-li podmínka splněna, cyklus svou činnost ukončuje. V opačném případě (splnění podmínky) dojde k vykonání příkazů umístěných v programovém bloku cyklu {}. Po dokončení jejich provádění dochází ke změně proměnné podle uživatelem zadaného vzorce (nejčastěji její zvýšení o 1). Poté se celý proces (vyjma úvodního nastavení) opakuje a dochází k opětovnému vyhondocení splnění podmínky.
Cyklus se skládá z klíčového slova for za kterým následují kulaté závorky () obsahující tři časti oddělené středníky:
inicializace proměnné (příklad: int pruchod=0; nebo i=1;) V této první části dochází k definici proměnné použité pro řízení programového cyklu a k nastavení její vychozí hodnoty. Proměnná musí být celočíselného datového typu Pokud je proměnná použita jen v rámci tohoto cyklu a nepožadujeme zachování její hodnoty pro zpracování mimo cyklus, je výhodné ji zadeklarovat jako místní proměnnou (int i=1;). Velmi častým názvem proměnné pro tento typ cyklů je i, jenž je zkratkou slova index. Při vnořování cyklů do sebe je pak též využívána proměnná j. Velmi vám proto doporučujeme, abyste proměnné tohoto jména používali výhradně pro cykly.
kontrola splnění podmínky (příklad: pruchod<5; nebo i<=128;) Ve druhé sekci se definuje podmínka obsahující proměnnou deklarovanou v předchozí části. Při splnění podmínky dojde k vykonání programového kódu umístěného v bloku cyklu. V případě že podmínka není splněna, je cyklus ukončen a je vykonán další příkaz následující za cyklem. Protože podmínka je testována před samotným provedením bloku cyklu, může se stát, že cyklus neproběhne ani jednou (příklad: v zásobníku balícího stroje není dostatečný počet zboží (žvýkaček), takže nelze balení po deseti kusech zkompletovat - čeká se na doplnění zboží).
krok - provedení změny proměnné (příklad: pruchod++; nebo i=i*2;) Po vykonání příkazů vnořených do cyklu je volán tento blok. Ten obsahuje vzorec pro změnu (zvýšení, snížení) obsahu proměnné. Přesto, že nejčastějším případem je zvýšení proměnné o jedna, je možné obsah proměnné změnit podle předem zadaného vzorce - např. výpočet mocnin čísla 2: i=i*2;.
Za touto sekcí se nachází blok kódu vykonávaný při jejím splnění. Blok kódu je umístěn do složených závorek {}. V tomto bloku je možno využít obsah proměnné určující průběh cyklu.
V následující ukázce vidíte použití cyklu pro postupné vypsání čísel 0 až 5 na displeji jendotky.
//CYKLUS S PEVNYM POCTEM PRUCHODU - PRIKLADfor(int i =0; i<5; i++){//opakovane vykonavany programovy kod//vypisujici na displeji postupne cisla od 0 do nxtDisplayTextLine(4,"%d", i);wait1Msec(500);}
Vnoření cyklů
Na následujícím programu můžete vidět využití vnoření cyklů v praxi. Program slouží k plnění blistru na tabletky složeného ze dvou řad. Pro umístění tabletek je využíváno vnoření cyklů s pevným počtem průchodů. Detailní popis programu je obsažen v komentářích.
taskmain(){//VNORENI CYKLU - PROGRAM BALICKA//Program slouzi k plneni blistru na tabletky paralenu//Blistr vzdy obsahuje dve rady tabletek po 5 kusech//Jamky na tabletky jsou od sebe vzdy ve stejne vzdalenosti//ZACATEK - jsem ve vychozi pozici nad prvni tabletkou//potrebuji v kazde ze dvou rad 5x po sobe umistit tabletku//a posunout se na dalsi pozici//nejprve vlozim cyklus pro vyber rady//protoze je pocet rad znamy, zvolim cyklus s pevnym poctem pruchodufor(int rada=1; rada<=2; rada++){//do kazde rady umistim 5 tabletek//i zvolim cyklus s pevnym poctem pruchodufor(int tabletka=1; tabletka<=5; tabletka++){//na displeji si vypisu, jakou tabletku plnimnxtDisplayTextLine(4,"r: %d, t: %d", rada, tabletka);//umistim tabletku - ovladano motorem Cmotor[motorC]=60;wait1Msec(200);motor[motorC]=-60;wait1Msec(200);//premistim se na dalsi pozici, ktera presne odpovida otoceni 126 stupnunMotorEncoder[motorA]=0;nMotorEncoderTarget[motorA]=126;//rozjedu motor na 45% vykonmotor[motorA]=45;//a necham ho otacet do doby, nez dosahnu ciloveho natoceni//zvolil jsem cyklus while, ktery okamzite testoval, zda nejsem uz spravnewhile(nMotorRunState[motorA]!= runStateIdle){//motor stale neni na spravne pozici, tak cekam, nez tam dojede//krome neustaleho testovani nedelam nic}//vypnu motormotor[motorA]=0;//jdu na dalsi tabletku}//zaplnil jsme celou radu tabletek, nyni se vratim na puvodni mistonMotorEncoder[motorA]=5*126;nMotorEncoderTarget[motorA]=0;motor[motorA]=-45;while(nMotorRunState[motorA]!= runStateIdle){}//vypnu motor posuvu plnickymotor[motorA]=0;//a posunu platicko na druhou radunMotorEncoder[motorB]=0;nMotorEncoderTarget[motorB]=253;motor[motorB]=45;while(nMotorRunState[motorB]!= runStateIdle){}//vypnu motor posuvu platickamotor[motorB]=0;//opakuji plneni rady ...}//nyni mam jiz naplnene platicko a vracim se do vychozi polohynMotorEncoder[motorB]=253;nMotorEncoderTarget[motorB]=0;motor[motorB]=-45;while(nMotorRunState[motorB]!= runStateIdle){}//vypnu motor posuvu platickamotor[motorB]=0;//cely tento kod mohu umistit do dalsiho cyklu, ktery bude provadet napr. baleni do krabicky}
Import z knihovny funkcí
Pokud si nepamatujeme názvy klíčových slov vykonávajících matematické funkce, můžeme je nalézt v knihovně funkcí (Function Library) sekci _C Constructs.
Po přetažení položek v sekcích Control Structures do programového okna dojde ke vložení námi zvoleného cyklu.
I když si to možná neuvědomujeme, denně řešíme celou řadu podmínek na jejichž základě se rozhodujeme. Když např. chceme přejít po přechodu na světelné křižovatce, podíváme se na semafor a zjistíme, zda svítí zelená barva. Pokud svítí červená, čekáme a sledujeme, zda se barva na semaforu nezměnila. Než začneme přecházet na zelenou, určitě se ještě rozhlédneme, jestli i řidiči aut zpozorovali, že mají zastavit. Celý náš den se tak skládá z celé řady podmínek, u kterých se při jejich splnění či nesplnění rozhodujeme, co provést.
V programu nám takovéto základní rozhodování (tentokrát ještě bez možnosti opakování - viz cykly) umožňují podmíněné příkazy. Velmi často se zapisují ve tvaru: "když něco platí, udělej tuto činnost(i)", nebo ve tvaru: "pokud toto platí, vykonej tyto činnosti, ale pokud to neplatí, vykonej tyto jiné činnosti". Př.: Pokud svítí zelená, zahaj přecházení, pokud nesvítí, čekej.
Ve skutečnosti však takovéto rozhodování nemusí být tak jednoduché a i v programu se může skládat z celé řady podmínek. Např. pokud svítí zelená a nic nejede nebo auta po levé ruce i auta po pravé ruce stojí, zahaj přecházení. V programu bychom toto mohli přepsat jako sérii navzájem se doplňujících či vyvracejících podmínek. Takovémuto vyjádření říkáme podmínkový výraz. Výslednou hodnotu (pravda / nepravda) pak získáváme až po jeho vyhodnocení.
Použití podmíněných příkazů v programovacím prostředí
Po přetažení bloku Switch, který nalezneme v paletě Complete > Flow, do okna programu dojde ke vložení výchozí bloku podmíněného programového vykonání.
V programovacím prostředí NXT-G se poněkud netradičně vyskytují podmíněné příkazy ve dvou variantách.
Blok podmíněného vykonání řízený hodnotou ze senzoru
V první variantě (Control: Sensor) je součástí bloku podmíněného vykonání i senzor, na základě jehož hodnoty a nastavené podmínky se rozhoduje, která část kódu bude vykonána. Při splnění nastavené podmínky se vykoná část označená symbolem případně alternativním symbolem vyjadřujícím splnění určité nastavené podmínky (např. ,,,,, ...), při nesplnění pak část opačná.
Nastavení podmínky je odlišné pro každý typ senzoru. Přesto jsou zde 4 základní typy nastavení, které si představíme na příkladech:
vznik události se vyskytuje např. u podmínky s dotykovým senzorem (Touch Sensor) . Zde volíme, ke které akci má dojít (tlačítko stisknuto, tlačítko uvolněno, tlačítko stisknuto a uvolněno), aby byla podmínka splněna.
podmínka porovnání je např. u senzoru rotací (Rotation Sensor) , kde se porovnává, zda je počet rotací větší (>) nebo menší (<) než zadaná hodnota.
rozsah se využije např. u senzoru barvy (Color Sensor) ve kterém pomocí posuvníku určíme horní a dolní mez načtené hodnoty určenou pro vyhodnocení splnění podmínky. Vybrat si tak můžeme barvy různých odstínů červené, nikoli jen jednu hodnotu.
přesně zadaná hodnota je např. u senzoru přijetí zprávy přes bluetooth (Receive Message) porovnávána s přijatou zprávou.
Blok podmíněného vykonání řízený vnější hodnotou
Blok podmíněného vykonání řízený vnější hodnotou je univerzálnějším typem podmínky. Hodnotu typu pravda / nepravda (true / false) lze na vstup bloku přivést z libovolného senzoru či z dalších rozšiřujících programových bloků a proměnných. Díky tomu lze kombinovat i podmínky z výstupů několika senzorů či proměnných či případně používat možnost kontroly rozsahu i u senzorů jenž to v předchozí variantě nepodporují.
Při pravdivosti (splnění) vstupu se vykoná část označená symbolem (zaškrtnutí - správně), při nesplnění pak část označená symbolem (křížek).
Volba flat view
Podobu bloku lze velmi výrazně změnit a v případě rozsáhlejšího programu i zpřehlednit vhodným využitím volby Flat view.
Při jejím zaškrtnutí jsou vykreslovány všechny části bloku podmíněného vykonání a to jak bloky při splnění, tak i bloky při nesplnění podmínky. Na první pohled je tak zřejmé, jaká část kódu se bude kdy vykonávat. Nevýhodou však je množství zabraného místa a to i u bloků, jenž v jedné větvi nic nevykonávají.
Odškrtnutím políčka Flat view se části kódu zobrazí jako záložky, nezi nimiž lze přepínat. Bloky tak sice nelze vidět najednou, ale u rozsáhlejších programů toto může být i výhoda.
Výběr z více položek
Dosud jsme při rozhodování vybírali ze dvou hodnot pravda / nepravda (splněno / nesplněno). V některých případech by se nám ale mohlo hodit rozlišovat více variant. Pro tuto možnost je ale nejprve nutno zrušit režim Flat view.
Jeho typ je nutno zvolit v parametrech bloku.
Parametry bloku
Volba typu cyklus se provádí v sekci Control a to z těchto možností:
Forever – nekonečný cyklus ukončitelný pouze koncem celého programu.
Time – časově omezený cyklus s podmínkou na konci, který testuje uplynutí času zadaného v parametru Seconds: v sekci Until:. Pro cyklus trvající půl vteřiny zde nastavíme Seconds: 0.5.
Logic – cyklus s podmínkou na konci, který o svém pokračování rozhoduje na základě logické hodnoty přivedené na rozhodovací vstup (obrázek ano/ne).
Sensor – je kombinací předchozího cyklu s výstupem senzoru. Senzor pak poskytuje informaci, zda z něj získaná hodnota splňuje námi nastavenou podmínku. Díky tomuto cyklu pak nemusíme vkládat blok senzoru a následné propojení s cyklem Logic.
Count – cyklus s pevným počtem průchodů. Počet průchodů se nastavuje v parametru Minimální počet průchodů a je stanoven na 1.
U všech cyklů lze pomocí parametru Show: Counter aktivovat výstup počítadla průchodů. To můžeme použít i pro zpracování ve vnitřní části cyklu (např. pro třídičku vykonávající odlišné operace pro sudá a lichá čísla).
Cyklus s podmínkou na začátku nejprve zkoumá, zda došlo ke splnění podmínky či podmínkového výrazu. Pokud je její výsledek pravda (true), vykoná vnořený kód (blok mezi složenými závorkami). Po jeho dokončení se cyklus vrací opět k podmínce a cyklus tak probíhá neustále dokola, dokud nedojde k nesplnění podmínky - nepravda (false).
Základní zápis cyklu
Cyklus se skládá z klíčového slova while za kterým následuje podmínka uzavřená do kulatých závorek (). Za nimi se nachází blok kódu vykonávaný při jejím splnění. Blok kódu je umístěn do složených závorek {}.
//CYKLUS S PODMINKOU NA ZACATKU while(true)//na misto true umistnete podminku ci podminkovy vyraz {//zde umistnete kod, ktery se ma opakovane vykonavat }
Z důvodu přehlednosti programu a odstraňování potencionálních chyb Vám doporučujeme se držet výše uvedeného formátování.
Příklad možné programové konstrukce
V následující ukázce kódu vidíte řešení přiblížení robota na vzdálenost cca. 20 cm od překážky. V případě, že se překážka nachází příliš blízko, motory se nerozjedou a robot zůstane stát.
//UKAZKA - PRIBLIZENI ROBOTA K PREKAZCE (ZDI) NA 20 CM//Robot otestuje, zda se pred nim nenachazi prekazkawhile(SensorValue[Ultrazvuk1]>20){//pokud ma pred sebou volno, prekazka je dale nez 20 cm, rozjede se//motor B a C se nastavi na 75% vykonmotor[motorB]=75;motor[motorC]=75;//protoze nehrozi kolize (prekazka je daleko) a neni tak potreba prilis//casteho testovani, nechame robota jet a dalsi test udelame za 100mswait1Msec(100);}//Cyklus skoncil, jsme na miste, vypiname motorymotor[motorB]=0;motor[motorC]=0;//Tento kod je mozno opakovat dle libosti a na rozdil od podminky na konci//nebude dochazet k neustalemu nepatrnemu priblizovani robota k prekazce
Cyklus s podmínkou na konci
Cyklus s podmínkou na konci nejprve provede příkazy umístěné v jeho těle a až následně zkoumá, zda má opětovně vykonat tento blok. Je-li podmínka či podmínkový výraz cyklu splněna (výsledná hodnota pravda (true)) bude cyklus vykonáván. Při hodnotě nepravda (false) se cyklus přeruší a pokračuje se v dalším běhu programu.
Základní zápis cyklu
Cyklus se skládá z klíčového slova do za kterým se nachází blok kódu, který je v případě splnění podmínky opakovaně vykonáván. Blok je uzavřený do složených závorek {}. Po nich následuje klíčové slovo while a podmínka či podmínkový výraz uzavřená do kulatých závorek (). Cyklus je zakončen středníkem ;.
//CYKLUS S PODMINKOU NA KONCIdo{//zde umistnete kod, ktery se ma opakovane vykonavat}while(true);//na misto true umistnete podminku ci podminkovy vyraz
Příklad možné programové konstrukce
V následující ukázce kódu vidíte řešení měřiče vzdálenosti, který počítá ujetou vzdálenost podle otáček motoru jež koeficientem přepočítává na ujetou vzdálenost. Pro snazší měření je začátek i konec měření spuštěn stiskem tlačítka.
//UKAZKA MERIC VZDALENOSTI//Meric vzdalenosti pocita pocet stupnu otoceni motoru,//ktere pak prepocita na vzdalenost a zobrazi na displeji//Ke spusteni i zastaveni mereni bude vyuzito tlacitko.//MERENI ZACNE STISKEM TLACITKAdo{//specialitou je, ze v teto sekci nebude zadny kod//opakovane se tedy bude vykonavat "nic"//jen se bude testovat, zda muzeme pokracovat}while(SensorValue(dotykovySenzor)==0);//tlacitko nestisknuto//VYMAZEME POCITADLO MOTORUnMotorEncoder[MotorA]=0;wait1Msec(1000);//nyni musi uzivatel do vteriny pustit tlacitko//A OPET TESTUJEME TLACITKOdo{}while(SensorValue(dotykovySenzor)==0);//tlacitko nestisknuto//VYPOCET VZDALENOSTI - obvod kola 12 cmfloat vzdalenost =nMotorEncoder[MotorA]/360*12;nxtDisplayTextLine(4,"%f", vzdalenost);//zobrazeni vzdalenosti na displ.wait1Msec(5000);//cekam, jinak by se displej smazal
Poznámka: V rámci zjednodušení řešení úlohy se předpokládá, že uživatel vždy stisknuté tlačítko do jedné vteřiny pustí. Pro přesnější realizaci by bylo vhodné reagovat spíše na uvolnění tlačítka.
Cyklus s pevným počtem průchodů
Cyklus s pevným počtem průchodů funguje ve třech režimech. V prvním inicializačním režimu, který nastává pouze při novém vstupu do cyklu nastaví výchozí hodnotu proměnné. Tu pak bude využívat pro řízení cyklu. V druhé části dochází k porovnání zadané podmínky. Není-li podmínka splněna, cyklus svou činnost ukončuje. V opačném případě (splnění podmínky) dojde k vykonání příkazů umístěných v programovém bloku cyklu {}. Po dokončení jejich provádění dochází ke změně proměnné podle uživatelem zadaného vzorce (nejčastěji její zvýšení o 1). Poté se celý proces (vyjma úvodního nastavení) opakuje a dochází k opětovnému vyhondocení splnění podmínky.
Cyklus se skládá z klíčového slova for za kterým následují kulaté závorky () obsahující tři časti oddělené středníky:
inicializace proměnné (příklad: int pruchod=0; nebo i=1;) V této první části dochází k definici proměnné použité pro řízení programového cyklu a k nastavení její vychozí hodnoty. Proměnná musí být celočíselného datového typu Pokud je proměnná použita jen v rámci tohoto cyklu a nepožadujeme zachování její hodnoty pro zpracování mimo cyklus, je výhodné ji zadeklarovat jako místní proměnnou (int i=1;). Velmi častým názvem proměnné pro tento typ cyklů je i, jenž je zkratkou slova index. Při vnořování cyklů do sebe je pak též využívána proměnná j. Velmi vám proto doporučujeme, abyste proměnné tohoto jména používali výhradně pro cykly.
kontrola splnění podmínky (příklad: pruchod<5; nebo i<=128;) Ve druhé sekci se definuje podmínka obsahující proměnnou deklarovanou v předchozí části. Při splnění podmínky dojde k vykonání programového kódu umístěného v bloku cyklu. V případě že podmínka není splněna, je cyklus ukončen a je vykonán další příkaz následující za cyklem. Protože podmínka je testována před samotným provedením bloku cyklu, může se stát, že cyklus neproběhne ani jednou (příklad: v zásobníku balícího stroje není dostatečný počet zboží (žvýkaček), takže nelze balení po deseti kusech zkompletovat - čeká se na doplnění zboží).
krok - provedení změny proměnné (příklad: pruchod++; nebo i=i*2;) Po vykonání příkazů vnořených do cyklu je volán tento blok. Ten obsahuje vzorec pro změnu (zvýšení, snížení) obsahu proměnné. Přesto, že nejčastějším případem je zvýšení proměnné o jedna, je možné obsah proměnné změnit podle předem zadaného vzorce - např. výpočet mocnin čísla 2: i=i*2;.
Za touto sekcí se nachází blok kódu vykonávaný při jejím splnění. Blok kódu je umístěn do složených závorek {}. V tomto bloku je možno využít obsah proměnné určující průběh cyklu.
V následující ukázce vidíte použití cyklu pro postupné vypsání čísel 0 až 5 na displeji jendotky.
//CYKLUS S PEVNYM POCTEM PRUCHODU - PRIKLADfor(int i =0; i<5; i++){//opakovane vykonavany programovy kod//vypisujici na displeji postupne cisla od 0 do nxtDisplayTextLine(4,"%d", i);wait1Msec(500);}
Vnoření cyklů
Na následujícím programu můžete vidět využití vnoření cyklů v praxi. Program slouží k plnění blistru na tabletky složeného ze dvou řad. Pro umístění tabletek je využíváno vnoření cyklů s pevným počtem průchodů. Detailní popis programu je obsažen v komentářích.
taskmain(){//VNORENI CYKLU - PROGRAM BALICKA //Program slouzi k plneni blistru na tabletky paralenu //Blistr vzdy obsahuje dve rady tabletek po 5 kusech //Jamky na tabletky jsou od sebe vzdy ve stejne vzdalenosti //ZACATEK - jsem ve vychozi pozici nad prvni tabletkou //potrebuji v kazde ze dvou rad 5x po sobe umistit tabletku //a posunout se na dalsi pozici//nejprve vlozim cyklus pro vyber rady //protoze je pocet rad znamy, zvolim cyklus s pevnym poctem pruchodu for(int rada=1; rada<=2; rada++){//do kazde rady umistim 5 tabletek //i zvolim cyklus s pevnym poctem pruchodu for(int tabletka=1; tabletka<=5; tabletka++){//na displeji si vypisu, jakou tabletku plnim nxtDisplayTextLine(4,"r: %d, t: %d", rada, tabletka);//umistim tabletku - ovladano motorem C motor[motorC]=60;wait1Msec(200);motor[motorC]=-60;wait1Msec(200);//premistim se na dalsi pozici, ktera presne odpovida otoceni 126 stupnu nMotorEncoder[motorA]=0;nMotorEncoderTarget[motorA]=126;//rozjedu motor na 45% vykon motor[motorA]=45;//a necham ho otacet do doby, nez dosahnu ciloveho natoceni //zvolil jsem cyklus while, ktery okamzite testoval, zda nejsem uz spravne while(nMotorRunState[motorA]!= runStateIdle){//motor stale neni na spravne pozici, tak cekam, nez tam dojede //krome neustaleho testovani nedelam nic }//vypnu motor motor[motorA]=0;//jdu na dalsi tabletku }//zaplnil jsme celou radu tabletek, nyni se vratim na puvodni misto nMotorEncoder[motorA]=5*126;nMotorEncoderTarget[motorA]=0;motor[motorA]=-45;while(nMotorRunState[motorA]!= runStateIdle){}//vypnu motor posuvu plnicky motor[motorA]=0;//a posunu platicko na druhou radu nMotorEncoder[motorB]=0;nMotorEncoderTarget[motorB]=253;motor[motorB]=45;while(nMotorRunState[motorB]!= runStateIdle){}//vypnu motor posuvu platicka motor[motorB]=0;//opakuji plneni rady ... }//nyni mam jiz naplnene platicko a vracim se do vychozi polohy nMotorEncoder[motorB]=253;nMotorEncoderTarget[motorB]=0;motor[motorB]=-45;while(nMotorRunState[motorB]!= runStateIdle){}//vypnu motor posuvu platicka motor[motorB]=0;//cely tento kod mohu umistit do dalsiho cyklu, ktery bude provadet napr. baleni do krabicky }
Import z knihovny funkcí
Pokud si nepamatujeme názvy klíčových slov vykonávajících matematické funkce, můžeme je nalézt v knihovně funkcí (Function Library) sekci _C Constructs.
Po přetažení položek v sekcích Control Structures do programového okna dojde ke vložení námi zvoleného cyklu.