Přestože jsem prohlašoval, že s robotickými a elektronickými články je konec, mám tady "jeden takový projekt" při jehož zpracovávání jsem si vzpoměl na to, že jsme sice probírali "oscilující" rozhodování jestli A = B nebo A > B, ale neprobrali jsme to nejjednodušší - jak přiměřeně "bezpečně" alias "blbuvzdorně" alias "robustně" programovat jednoduché dvoustavové rozhodování - tedy máte teplotu a rozhodujete zda je "horko" nebo "zima" - máte světelnou intenzitu a rozhodujete zda je "světlo" nebo "tma" neboli máte analogový - numerický - signál z čidla a vy musíte dynamicky rozhodnout zda je to "málo" nebo "hodně".
Při té příležitosti bych si dovolil upozornint, že už kdysi dávno jsem prohlašoval, že čidlo, které produkuje jenom informaci ANO nebo NE - je nebezpečné a nemělo by se v robotech používat. A taky jsem kdysi prohlašoval, že veškerá čidla, která jsem kdy postavil dávala dokonce až DVĚ výstupní hoddnoty
- Samotnou "intenzitu signálu" ( ne ANO / NE ) ale v analogové škále
- Analogovou informaci o "kvalitě" tedy jak mnoho je si dané čidlo touto hodnotou jisto.
Takže si modelově ptředstavme tu nejjednodušší situaci - robot má měřič intenzity světla a má určit zda je "na slunku" nebo "ve stínu". Předpokládejme, že měřič má jednoduchý AD výstup, kde 0 je "absolutní tma" a 255 je "absolutní světlo". Taky si představme, že vůbec netušíme jakou hodnotu má stav "trochu šero" nebo "docela jasno" a přesto musíme nějak rozhodnout. Ba dokonce si představme, že hodnota "středně šero" nemusí být 128 - jak bychom naivně očekávali.
Víte co potom ? Opět částečně naivní postup je získat nějakou "rozhodovací mez" tedy třeba "pod 60 je to ve stínu", ale jak se k takové mezi dopracovat ? Dosti často se používá "startovní kalibrace" tedy změří se hodnota "než se vyjede" a od ní se pak odvodí rozhodovací limit. Někdy to funguje, ale představte si robota, který startuje a netuší jestli přitom stojí ve stínu, nebo na slunku. A potom některá čidla, aby zvládla třena venkovní světelné intenzity, mohou mít velice úzké rozmezí jako 63 je světlo a 58 je už tma ?
Předpokládám, že jste právě propadli nihilismu a odpovědí na mé otázky je prohledat "Aliexpress" s příslušným čtyřdírkovým modulem pro "Arduííno" a pokud Číňani nic nevymysleli ( neukradli chytřejším ), máte tendenci předvést, že nejste chytřejší než Číňani - a na všecno se vykašlat ?
Nicméně to by nebyl tento blog, aby nějaké "vidlácké" ba dokonce "assemblerové" východisko nebylo. Berte tedy tento článek jako informaci, jak v mých robotech probíhá ( probíhalo ) jednoduché rozhodování typu SVĚTLO / TMA nebo prostě ANO / NE.
Celé kouzlo je v tom, že není jedna rozhodovací mez, ale DVĚ, který říkejme INTENZITA_SVĚTLA a INTENZITA_TMY. Pokud tedy předpokládáme vstup v hodnotách 0-255 je dobré obě intenzity na začátek nastavit na střední hodnotu 127.
Pak přijde nějaká hodnota z AD převodníku a pro rozhodování obecně platí
- Pokud NOVÁ_HODNOTA <= INTENZITA_TMY pak je výsledek TMA
- Pokud NOVÁ_HODNOTA >= INTENZITA_SVĚTLA pak je výsledek SVĚTLO
- Pokud je výsledek uprostřed mezi oběma "intezitami" - rozhodne se podle toho zda je NOVÁ HODNOTA blíže k hodnotě INTENZITY_SVĚTLA nebo k hodnotě INTEZITY_TMY
Mimochodem "numerická vzdálenost" na jednorozměrné číselné ose se počítá jako ABS ( NOVÁ_HODNOTA - INTENZITA_SVĚTLA ) případně jako ABS ( NOVÁ_HODNOTA - INTENZITA_TMY ). Takto složitě to však dělat nemusíme, porotože vyloučením varianty 1 a 2 víme. že NOVÁ_HODNOTA je uprostřed tedy naše zjednodušená podmínka bude
IF ( NOVÁ_HODNOTA - INTENZITA_TMY ) > ( INTENZITA_SVĚTLA - NOVÁ_HODNOTA ) THEN světlo ELSE tma
Co dělat v případě, že NOVÁ_HODNOTA je naprosto přesně uprostřed - nevím, ale v reále to za mně vyždy vyřešily nestability hodnot čidel, které způsobily, že výsledek se vždy nakonec "někam skulil".
Doposud se to zdá být jenom příliš složité řešení prajednoduché věci, ale teď přijde "genialita Cimrmanovy myšlenky" - poté co jsme rozhodli zdali výsledek je SVĚTLO nebo TMA - vezmeme příslušný limit a jeho hodnotu "updatujeme" nějakým třeba - dosti dlouhým exponenciálním klouzavým průmerem.
Příklad - vyšla nám "tma" tak provedeme následující výpočet
INTEZITA_TMY = ( 7 * INTENZITA_TMY + HODNOTA ) >> 3
neboli bez assemblerovských bitových posuvů
INTEZITA_TMY = ( 7 * INTENZITA_TMY + HODNOTA ) / 8.
totéž s INTENZITOU_SVĚTLA, pokud je výsledek "světlo".
Matematikům mezi vámi, což jsou ostatně všichni - je to jasné. Kouzlo je totiž v tom, že po čase se INTEZITA_SVĚTLA dostane na typické hodnoty pro výsledek SVĚTLO a INTENZITA_TMY se dostane na hodnoty typické pro výsledek TMA.
To stále vypadá jako zbytečná kravina, ale není. Používání dvou limitů tímto způsobem má v sobě to kouzlo, že rozdíl mezi nimi nám dává potřebnou informaci o "kvalitě" neboli "blbuvzdornosti" rozhodování. Takže pokud po nějaké době jízdy je INTENZITA_TMY = 30 a INTENZITA SVĚTLA = 210 - je jasné, že čidlo je kvalitní a robot je si svými rozhodnutími perfektně jistý.
Pokud naopak i po nějaké době jízdy platí že INTENZITA_TMY ( téměř ) = INTENZITA SVĚTLA je jasné, že čidlo i jeho závěry nestojí za nic. Ba dokonce, pokud budeme úplní matematici - můžeme si krom "průměrných intenzit" počítat i jejich směrodatné odchylky a podle nich určit s jakou "statistickou významností" se obě intenzity liší a tudíž určit jestli "nejistota rozhodnutí" je 20, 10, 5, 1, nebo ještě méně procent. To je složitost, kterou sice umím, ale nikdy jsem ji v robotech nepoužíval, tudíž bych ji nechal na někdy jindy.
Detailisti mezi čtenáři jistě namítnou, že ani tento způsob není chráněn před špatnými rozhodnutími, hlavně na samém začátku. Ano je to pravda - tento algoritmus má potenciál rozhodovat stejně špatně jako prosté porovnání proti jednomu limitu. Na druhé straně chyba rozhodnutí v tomto algorimtu není "překvapivý zásah nepříznivého osudu" a dá se dopředu odhadnout, pokud se oba limity liší jenom málo. Což mimochodem vzhledem k nastavení obou "doprostřed škály" - je pravda i na začátku, při startu robota.
Jasné ?