diff --git a/docs/lekce.txt b/docs/lekce.txt new file mode 100644 index 0000000..cfd0b33 --- /dev/null +++ b/docs/lekce.txt @@ -0,0 +1,39 @@ +Táborové lekce: želvička 2024 + +Technický blok: +Instalace Jaculus a IDE (simulátor?) +Bezdrát, ovládání přes bt (?) +Mechanická výroba (?): skládání robota a mechanické zvedání tužky, nárazníky? +Bločky? +Diferenciální řízení +Senzorika + +Základy programování: +Struktura programu +Proměnné a podmínky +Události (první tři asi lze převzít z minulého tábora) +Řídicí struktury (tady by se to pěkně ukazovalo v simulátoru s kreslící želvičkou) +Řetězce +Rekurze (?) +OOP (?) + +Základy algoritmiky: +Graf +Fronta, zásobník +Hledání nejkratší cesty + +Jízda v bludišti a po čáře - úvodní lekce + +Projekty: skupinky, soutěž o nejlepší čas + +Simulátor specifikace: +- 2D vykreslování +- Schopnost kreslit čáry a překážky, export a import JSON +- Řízení robota: z klávesnice nebo jako popis instrukcí + + Šipky pro zrychlení: pravá-levá zvedne rychlost jednoho z motorů, dopředu a dozadu sníží rychlost obou současně (?) + + Pseudokód (JavaScript?) specifikující chování robota (e.g. když narazím na čáru nebo detekuju zeď - změním směr, nebo pomocí cyklů (událostí) kreslím obrázek) +- Senzorika: + + Senzory čáry tak jak jsou na robotovi, přepínání mezi krajními a čárovými jedním tlačítkem + + Lidar: dám si ho na robota jak chci, ručně nasměruji, potom mi při požadavku čtení vrátí vzdálenost zdi kterou našel. + Ve směru překážky mi vrací normální rozdělení kolem skutečné hodnoty, ve větší vzdálenosti s nějakou pravděpodobností selže. + Hodnoty bych dal nastavitelné (pro nás, abychom to upravili na základě skutečných hodnot), ale dětem už bych je zafixoval a schoval. diff --git a/docs/robot/lekce1/index.md b/docs/robot/lekce1/index.md index e65cbbd..3085d81 100644 --- a/docs/robot/lekce1/index.md +++ b/docs/robot/lekce1/index.md @@ -4,11 +4,14 @@ V této lekci si představíme Jaculus, nainstalujeme si programovací prostřed ## Instalace -Pro práci s Jaculem je nutné nainstalovat několik programů. +Na našich robotech běží program, který se jmenuje Jaculus. +Tento program nám umožní jednoduše psát instrukce (programy), které nahrajeme do robota. +Tyto programy budou specifikovat, jak se robot má chovat, a umožní nám s ním komunikovat. +Aby nám všechno správně fungovalo, musíme nejprve nainstalovat několik programů. ### Node.js -Node.js je program, který nám umožní nahrávat kód do Jacula a komunikovat s ním. +`node.js` je knihovna, která nám umožní stáhnout nástroje na používání Jacula. 1. Stáhneme si [Node.js](https://nodejs.org/en/download) (nejnovější stabilní verzi - LTS) 2. Nainstalujeme jej dle výchozího nastavení (není potřeba nic měnit). @@ -22,10 +25,10 @@ Visual Studio Code je programovací prostředí, které nám umožní psát kód ### Jaculus -Jaculus je program, který nám umožní nahrávat kód do Jacula a komunikovat s ním. +Nyní už se můžeme vrhnout na samotnou instalaci [`Jacula`](https://jaculus.org/getting-started/). -1. Po instalaci Nodu **restartujeme** aplikaci Visual Studio Code. -2. V horním menu VSCode vyberte záložku `Terminal` a zvolíme `New Terminal`. +1. Po instalaci `node` **restartujeme** aplikaci Visual Studio Code. +2. V horním menu VSCode vybereme záložku `Terminal` a zvolíme `New Terminal`. 3. Do terminálu zadáme příkaz vypsaný níže. Na `Linuxu` bude nejspíše potřeba `sudo` práva. ```bash @@ -187,4 +190,4 @@ Ve zdrojovém kódu jsou komentáře (`// tohle je komentář`), které nám pop const ledStrip = new SmartLed(LED_PIN, LED_COUNT, LED_WS2812); // připojí pásek na pin 48, s 1 ledkou a typem WS2812 ... - ``` \ No newline at end of file + ``` diff --git a/docs/robot/lekce2/index.md b/docs/robot/lekce2/index.md index 86994e4..4227090 100644 --- a/docs/robot/lekce2/index.md +++ b/docs/robot/lekce2/index.md @@ -1,8 +1,12 @@ # Lekce 2 - RGB LED + tlačítko + události -V této lekci si ukážeme ovládání RGB LED umístěné na ESP32 a práci s událostmi řízenými tlačítkem nebo časem. +V této lekci si napíšeme své první programy. -Jelikož je TypeScript (JavaScript) imperativní, vykonávájí se příkazy v takovém pořadí, v jakém jsou zapsány. +Ukážeme si ovládání RGB LED umístěné na ESP32 a práci s událostmi řízenými tlačítkem nebo časem. + +TypeScript (JavaScript) je imperativní programovací jazyk. Znamená to, že se vykoná vše co do programu napíšeme, +v takovém pořadí jak jsme to zapsali. Programy mají řadu věcí co v nich umíme zapsat, nám zatím budou stačit +nejzákladnější příkazy: i velice jednoduchý program už může mít viditelný výsledek. [Stáhnout ZIP s prázdným projektem](./blank_project.zip){ .md-button .md-button--primary } @@ -82,7 +86,9 @@ Pomocí událostí rozsvítíme při stisknutí tlačítka (GPIO 0) RGB LED na E ## Zadání C -Dvakrát za sekundu vypíšeme stav zmáčknutí tlačítka (0 nebo 1). Opakování dosáhneme pomocí `setInterval()`. Stav daného tlačítka získáme pomocí `#!ts gpio.read(číslo pinu)`. +Dvakrát za sekundu vypíšeme stav zmáčknutí tlačítka (0 nebo 1). Stav daného tlačítka získáme pomocí `#!ts gpio.read(číslo pinu)`. + +Vzpomeňme si z prvního programu, že opakování dosáhneme pomocí `setInterval()`, a informaci vypíšeme pomocí `#!ts console.log()`. ??? note "Řešení" ```ts @@ -97,10 +103,10 @@ Dvakrát za sekundu vypíšeme stav zmáčknutí tlačítka (0 nebo 1). Opaková }, 500); // čas opakování se udává v milisekundách (500 ms je 0,5 sekundy) ``` -## Zadání výstupního úkolu V1 +## Výstupní úkol V1 - Pozdrav Při stisknutí tlačítka (GPIO 0) vypíšeme pozdrav. -## Zadání výstupního úkolu V2 +## Výstupní úkol V2 - Změna barvy Při stisknutí tlačítka (GPIO 0) rozsvítíme RGB LED na ESP32 (`GPIO 48`) jednou barvou a při puštění barvu změníme na jinou. diff --git a/docs/robot/lekce3/index.md b/docs/robot/lekce3/index.md index b86742e..f58456d 100644 --- a/docs/robot/lekce3/index.md +++ b/docs/robot/lekce3/index.md @@ -1,7 +1,7 @@ # Lekce 3 - proměnné a podmínky V imperativním programování si držíme stav pomocí **proměnných**. Proměnné jsou pojmenované hodnoty, -které mají nějakou hodnotu, můžeme je měnit, a opakovaně používat v různých částech kódu. +které můžeme měnit, a opakovaně používat v různých částech kódu. Proměnná má svůj typ, který určuje, jaké hodnoty může proměnná mít. Proměnnou vytvoříme pomocí klíčového slova `let`. @@ -122,7 +122,7 @@ Pomocí jedné proměnné se stavem a podmínky každou sekundu buď rozsvítím ## Zadání B -Pomocí funkce `colors.rainbow` budeme procházet duhu. Jde o funkci, která dostane číslo od 0 do 360, +Pomocí funkce `colors.rainbow` budeme procházet duhu. Jde o funkci (o těch si povíme trochu více později), která dostane číslo od 0 do 360, a na základě toho vrátí barvu na barevném spektru. V daném intervalu (např. 100 ms) budeme postupně zvyšovat číslo a nastavovat barvu LEDky na `colors.rainbow(cislo)`. Pokud naše číslo přesáhne hodnotu `360`, musíme ho opět nastavit na `0`. @@ -185,9 +185,9 @@ Pokud při stisku tlačítka svítí poslední LED, zhasneme ji, a rozsvítíme }); ``` -## Výstupní úkol V1 +## Výstupní úkol V1 - Knightrider -Knightrider: svítící LED "běhá" s danou rychlostí od začátku do konce pásky. +Svítící LED "běhá" s danou rychlostí od začátku do konce pásky. Jakmile dorazí na konec, změní směr, a posouvá se opačným směrem. V našem případě bude stačit, když se bude pohybovat pouze jedna LEDka. diff --git a/docs/robot/lekce4/index.md b/docs/robot/lekce4/index.md index 49bac9a..082220c 100644 --- a/docs/robot/lekce4/index.md +++ b/docs/robot/lekce4/index.md @@ -1,6 +1,10 @@ # Lekce 4 - cykly V této lekci si představíme cykly, což je nástroj který nám umožňuje opakovat kód podle nějakého pravidla. +Zatím je využijeme pro komunikaci s robotem, v následující lekci si ukážeme jejich použití při řízení robota. + +(Nejsem si jistý jak moc tady tu lekci chceme. Přijde mi to méně zajímavé než jezdit s želvičkou, ale když jsem se to snažil dát do jedné lekce, přišla mi moc dlouhá.) + Máme primárně dva typy cyklů: - `#!ts for` pro případ kdy víme kolikrát se cyklus má opakovat @@ -19,9 +23,12 @@ Do kulatých závorek píšeme tři věci: - výraz který určuje počet opakování - nakonec jednoduchou operaci která se provede při každém průchodu cyklem jako poslední operace -Tedy zakládáme proměnnou `#!ts i` s výchozí hodnotou `#!ts 0`, následně definujeme výraz `#!ts i < 3 ` a na konci cyklu zvýšíme `#!ts i ` o jedna. +Tedy vytváříme proměnnou `#!ts i` s výchozí hodnotou `#!ts 0`, která bude existovat po dobu toho, co se vykonává cyklus. +Ačkoliv v běžném životě počítáme věci od `1`, v informatice častěji začínáme `0`. Může zde však být cokoliv. + +Následně definujeme výraz `#!ts i < 3 `, který značí, kdy se cyklus má zastavit. Na konci cyklu zvýšíme `#!ts i ` o jedna. Při prvním průchodu bude tedy `#!ts i = 0` při druhém `#!ts i = 1 ` a při třetím `#!ts i = 2 ` při dalším zvyšování by platilo `#!ts i = 3 ` tam ale už nebude pravdivý výraz ` i < 3 ` a cyklus se tedy ukončí. -Do složených závorek píšeme vykonávaný kód. +Do složených závorek píšeme vykonávaný kód, který se v tomto případě vykoná 3-krát. Kostru na tento úkol najdete [zde](./project4.zip). @@ -35,7 +42,7 @@ Kod napište tak aby bylo jednoduché ho upravit na výpis jakéhokoli jiného i const BTN_PIN = 18; - gpio.pinMode(BTN_PIN, gpio.PinMode.INPUT_PULLUP); // nastaví pin nula jako vstup + gpio.pinMode(BTN_PIN, gpio.PinMode.INPUT); // nastaví pin 18 jako vstup gpio.on("falling", BTN_PIN, () => { // událost, která proběhne při stisknutí tlačítka připojeného na pin 0 console.log("Stisknuto, začínáme počítat"); @@ -47,7 +54,7 @@ Kod napište tak aby bylo jednoduché ho upravit na výpis jakéhokoli jiného i ``` ## Cyklus while -Pokud nevíme kolikrát se má cyklus opakovat použijeme místo cyklu `#!ts for ` cyklus `#!ts while `. +Pokud nevíme, kolikrát se má cyklus opakovat, použijeme místo cyklu `#!ts for ` cyklus `#!ts while `. Do kulatých závorek teď píšeme jen výraz který určuje jestli se cyklus vykoná znovu nebo ne. Kód, který se má vykonávat, dokud platí podmínka, vypadá takto: @@ -56,40 +63,8 @@ while (condition - podmínka) { // náš kód } ``` - - - - ## Zadání B Nyní napište kód který do konzole vypíše čtverec složený z hvězdiček (znaku `*`), diff --git a/docs/robot/lekce4/turtle.md b/docs/robot/lekce4/turtle.md new file mode 100644 index 0000000..f051d7d --- /dev/null +++ b/docs/robot/lekce4/turtle.md @@ -0,0 +1,105 @@ +# Lekce 4.5 - želvička + +Tato lekce přímo navazuje na předchozí, a ukazuje praktické použití cyklů. + +## Želvička + +Cykly si vyzkoušíme v programu `Želvička (TODO název?)`. Program obsahuje zjednodušenou verzi reality, ve které nám bude jezdit želvička a přijímat příkazy na základě vnějších podnětů. + +// TODO Obrázek a link na simulátor + +Programy nám budou fungovat i na skutečném robotovi. Je však je důležité nejdříve si v simulaci ověřit funkčnost, aby se nám skutečný robot nezačal chovat neočekávaným způsobem a nezpůsobil sobě nebo nám škody. + +Program má textové okno, kam můžeme psát příkazy. Zatím jsou pro nás zajímavé příkazy (TODO přesná specifikace): + +`motors.rotate(deg)` - želvička se otočí o `deg` stupňů po směru hodinových ručiček +`motors.move(dist)` - želvička se pohne dopředu o `dist` centimetrů + +Zatím pro jednoduchost uvažujme, že se želvička umí buď otáčet, nebo jet dopředu, ale ne obojí zároveň. V kapitole (TODO diferenciální řízení) si ukážeme pokročilejší způsob jak ji řídit. +Jízdu obloukem zatím budeme řešit tak, že opakovaně popojedeme o maličký kousek, a poté se trošku otočíme. + +## Zadání A + +Napište program, který z výchozí pozice želvičky vyjede o kousek dopředu, objede čtverec, a vrátí se zase zpět. + +// TODO gif? nebo prostě ukázat na lekci + +??? note "Řešení" + ```ts + import * as motors from "motors"; // ovládání motorů + + for (let i: number = 0; i < 4; i++) { // chování opakujeme 4x, pro každou stěnu čtverce + motors.move(10); // posun dopředu o 10 cm + motors.rotate(90); // rotace doprava o 90 stupňů + } + ``` + +Toto chování můžeme také provést v reakci na událost. Modifikujte program tak, aby želvička projela čtverec až po stisknutí tlačítka. + +??? note "Řešení" + ```ts + import * as gpio from "gpio"; + import * as motors from "motors"; // ovládání motorů + + + const BTN_PIN = 18; + gpio.pinMode(BTN_PIN, gpio.PinMode.INPUT); // nastaví pin 18 jako vstup + gpio.on("falling", BTN_PIN, () => { // reakce na stisk tlačítka + for (let i: number = 0; i < 4; i++) { // chování opakujeme 4x, pro každou stěnu čtverce + motors.move(10); // posun dopředu o 10 cm + motors.rotate(90); // rotace doprava o 90 stupňů + } + }); + ``` + +### Kreslení + +Želvička kromě jízdy umí i kreslit. Má v sobě tužku, kterou může buď zvednout, nebo položit. +Slouží na to příkaz: + +`motors.draw(pravdivostní hodnota)` - Tato funkce určuje, jestli má želvička kreslit, nebo ne. Hodnota `true` nám říká, že máme tužku položenou na zemi (tj. kreslíme), hodnota `false` že nekreslíme. + +Na skutečném robotovi nám kreslení bude fungovat po nainstalování fixy podle (TODO manuální konstrukce). + +## Zadání B + +Vraťme se k předchozímu příkladu. Abychom věděli, že želvička skutečně projela čtverec, necháme ji nakreslit ho. Dopíšeme tedy program tak, aby po stisku tlačítka položila tužku, nakreslila čtverec, a následně tužku zase zvedla. + +??? note "Řešení" + ```ts + import * as gpio from "gpio"; + import * as motors from "motors"; // ovládání motorů + + + const BTN_PIN = 18; + gpio.pinMode(BTN_PIN, gpio.PinMode.INPUT); // nastaví pin 18 jako vstup + gpio.on("falling", BTN_PIN, () => { // reakce na stisk tlačítka + motors.draw(true); + for (let i: number = 0; i < 4; i++) { // chování opakujeme 4x, pro každou stěnu čtverce + motors.move(10); // posun dopředu o 10 cm + motors.rotate(90); // rotace doprava o 90 stupňů + } + motors.draw(false); + }); + ``` + +## Výstupní úkol V1 - Trojúhelník + +Napište kód, který způsobí, že želvička nakreslí místo čtverce trojúhelník. Rozměry trojúhelníku jsou na vás, jen musí skutečně jít o trojúhelník. + +!!! tip "Trojúhelníková nerovnost (nechť `a`, `b`, `c` jsou délky stran)"" + ```math + a + b > c + a + c > b + b + c > a + ``` + + Na zjištění úhlu, o který je potřeba se otočit, můžeme použít kosínovu větu (Dodat jako knihovní funkci, tak jako barvičky). + + +## Výstupní úkol V2 - Domeček + +Propojte dosavadní znalosti do jednoho kódu. +Napište program, který způsobí že si želvička nakreslí domeček z čtverce a trojúhelníkové střechy. + +Následně želvička přestane kreslit, a vjede doprostřed domečku, kde zastaví.