7 Snímanie čiary
V predchádzajúcich návodoch sme si ukázali, ako môžeme ovládať motory a s robotom pomocou Stateflow namodelovať postupnosť operácií. Ako ale zabezpečíme, aby robot sledoval čiaru? Na sledovanie čiary potrebujeme snímač, ktorý rozlíši či je pod ním biela alebo čierna farba. V tomto návode si povieme o snímači, ktorý je dostupný v stavebnici.
Čo budeme potrebovať?
V tomto návode nadviažeme na robota, ktorého sme zložili v predchádzajúcej časti. Na spodnú časť robota pripevníme snímač čiary, ktorý je priložený v stavebnici. Snímač pripojíme pomocou kábla a prepojovacích káblov na 5V (červená), zem Arduina (čierna) a na analógové piny A0 - A4 (biela - zelená - oranžová - žltá - modrá). Na testovania snímača si môžeme vytlačiť jednu časť dráhy z návodov.
Infračervený (IR) snímač
Najčastejší spôsob ako detegovať čiaru pod robotom je využitie infračerveného snímača. Snímač obsahuje pár infračervených diód. Vysielačom je IR LED, ktorá vysiela svetlo špecifickej vlnovej dĺžky (infračerveného spektra). Pokiaľ je pred snímačom prekážka, svetlo sa odráža na prijímač. Prijímač je fotodióda, ktorá deteguje svetlo špecifickej dĺžky. Podľa množstva odrazeného svetla dokážeme rozoznať, aký svetlý je objekt pred snímačom. Svetlejšie objekty odrážajú viac svetla ako tmavšie [1].
Na sledovanie čiary potrebujeme viacero IR snímačov. V našom prípade využijeme snímač Waveshare Tracker Sensor, ktorý obsahuje 5 IR snímačov (kanálov). Odporúčaná vzdialenosť detekcie je 1cm - 5cm a hodnoty môžeme snímať pomocou analógových vstupov Arduina.
Čítanie snímačov z MATLABu
Skôr ako začneme čítať hodnoty snímača v Simulinku, overíme si jeho činnosť v MATLABe. Vytvorme objekt pre spojenie s Arduinom
a=arduino
Pomocou metódy objektu Arduina readVoltage prečítame jednotlivé hodnoty na snímačoch. Aby sme mohli všetky hodnoty vypísať do jedného riadku použijeme funkciu sprintf.
a0=a.readVoltage('A0');
a1=a.readVoltage('A1');
a2=a.readVoltage('A2');
a3=a.readVoltage('A3');
a4=a.readVoltage('A4');
sprintf('A0: %.3f, A1: %.3f, A2: %.3f, A3: %.3f, A4: %.3f',a0,a1,a2,a3,a4)
Položte robota tak, aby všetky snímače čiary boli na bielej farbe. Potom postup opakujte s čiernou farbou. Čo ste si všimli? Ak boli snímače na bielej farbe hodnoty analógového vstupu by mali byť väčšie, ako keď boli snímače na čiernej farbe. Ďalej môžeme sledovať, že nie všetky snímače dávajú podobnú (blízku) hodnotu. Môže to byť spôsobené viacerými faktormi. Konštrukciou uloženia snímača, prípadne svetlom, ktoré prichádza na podložku alebo snímač (tento vplyv vieme čiastočne potlačiť priloženou krytkou) a podobne. Po skončení práce vymažeme objekt Arduina.
clear a
Čítanie snímačov zo Simulinku
Na čítanie snímačov ovládanie motorov zo Simulinku použijeme nasledujúce bloky
- Simulink Support Package for Arduino Hardware - Common - Analog Input
- Simulink - Signal Routing - Mux
- Simulink - Math Operations - Gain
- Simulink - Sinks - Display
V blokoch Analog Input nastavíme jednotlivé porty a periódu vzorkovania na 0.01 sekundy. Pomocou bloku Mux spojíme signály do jedného vektora. Aby sme dostali rovnaký rozsah hodnôt ako v MATLABe, využijeme blok Gain. Pomocou zosilnenia 5/1023 prevedieme rozsah 0-1023 na rozsah 0-5. V bloku Gain zmeňte v záložke Signal Attributes - Output data type na double, aby sme nepočítali iba s celými číslami, ktoré vracajú bloky Analog Input. Hodnoty si zobrazíme blokom Display. Nastavte pre schému koncové zariadenie Arduino MEGA 2560, čas do nekonečna a model môžete spustiť pomocou tlačidla Monitor & Tune.
Normalizácia
Ako sme si už všimli, viaceré snímače môžu dať rôzne hodnoty pre rovnakú farbu a vzdialenosť. Tieto hodnoty sa môžu navyše meniť vplyvom okolia. Tieto vplyvy môžeme potlačiť normalizáciou hodnôt. Normalizáciu vykonáme nasledujúcim vzťahom
Do Simulinku teda pridáme nasledujúce bloky
- Simulink - Math Operations - MinMax Running Resetable
- Simulink - Sources - Constant
- Simulink - Math Operations - Subtract
- Simulink - Math Operations - Divide
- Simulink - Math Operations - Gain
V našej schéme využijeme 2 bloky MinMax Running Resetable - jeden pre minimum a jeden pre maximum. Zmeňte v jednom bloku operáciu na minimum a počiatočnú hodnotu nastavíme podľa predchádzajúceho pozorovania bližšie od stredu ku menším hodnotám teda na 2. V druhom bloku nastavíme maximum ako operáciu a počiatočnú hodnoty zvolíme bližšie ku väčším hodnotám teda na 3. Tieto bloky sa budú aktualizovať na najmenšiu, prípadne najväčšiu hodnotu, ktorú dostali počas behu programu. Aby sa neresetovali pripojíme na vstupy R konštantu 0. Ďalšie bloky slúžia na matematické operácie, ktoré sú v predošlom vzťahu. Spustite model a pozorujte, čo sa deje ak robota posúvate snímačom cez čiaru jednotlivými snímačmi.
Pokiaľ prejdeme snímačom od bielej farby cez čiernu nastavia sa skutočné hodnoty pre bielu a čiernu (maximum a minimum). Hodnoty, ktoré po normalizácii dostaneme budú pre čiernu blízke 0 a pre bielu blízke 100. Aby sme schému trošku zjednodušili na čítanie v budúcnosti môžeme bloky, ktoré so sebou logicky súvisia "zabaliť" do subsystému. Označíme bloky, ktoré sme použili na normalizáciu a pomocou pravého kliku a voľby Create Subsystem from Selection.
Subsystém vieme dvojklikom na meno bloku zmeniť. Ak by ste mená blokov nevideli, môžete si ich zapnúť odznačením položky v záložke Debug - Information Overlays odznačením voľby Hide Automatic Block Names.
Ak by sme chceli dostať zo snímačov iba binárne výstupy (1 pre čiernu ak sme na čiare a 0 pre bielu) porovnáme, či je signál menší ako stredná hodnota teda 50. Použijeme blok
- Simulink - Logic and Bit Operations - Compare To Constants
Z obrázku je vidno, že snímačom sme boli stredným a vedľajším snímačom na čiare po počiatočnej kalibrácii. Aby snímač pracoval správne treba na začiatku prejsť všetkými snímačmi po bielej a čiernej farbe, aby sa algoritmus naučil, čo je biela a čo čierna farba (minimá a maximá). Ak by ste chceli rozdeliť signály na jednotlivé snímače použite blok Demux. Blok na získanie binárnych výstupov zo snímačov blok na chvíľku zmažeme, ale neskôr znovu pridáme. V nasledujúcej časti si predstavíme vážený priemer. Skôr ako to urobíme môžeme si ešte otočiť signál tak, že čierna bude bližšie ku 100 a biela bližšie ku 0. Urobíme to tak, že od konštanty 100 odpočítame normalizovaný signál. Dôvod prečo to robíme je, že po vážení bude jasnejšie ktoré snímače majú vplyv na vážený priemer. Otočené signály budeme používať aj v nasledujúcich návodoch (pokiaľ chcete používať vážený priemer bez úpravy dajte do konštanty 0).
Vážený priemer
Ako ďalšie potrebujeme previesť hodnoty 5 snímačov a pozíciu čiary. Toto vieme dosiahnuť pomocou váženého priemeru nasledujúcim vzťahom
Pomocou tohoto vzťahu prevedieme detekcie na rozsah 100 - 500, kde 300 znamená, že sa robotom nachádzame v strede čiary. Do schémy doplníme ďalší bloky
- Simulink - Math Operations - Gain
- Simulink - Math Operations - Divide
- Simulink - Math Operations - Sum of Elements
Blokom Sum of Elements sčítame jednotlivé vstupy vektora a vektorové násobenie po prvkoch dostane tak, že do bloku Gain pridáme transponovaný vektor a nastavíme operáciu ako Matrix (u*K) Multiplication.
Z výstupu na bloku Display sa môže zdať, že je robot na čiare skoro v strede. Hodnota 300 však neznamená, že ide o tretí senzor v poradí. Zvyšné senzory nedávajú nikdy presne nulové hodnoty, vzhľadom na svetelné podmienky. Pohybujte sa robotom po čiare z boku na bok a sledujte hodnoty na výstupe a pozície snímačov nad čiarou. Pre vážený priemer môžeme tiež vytvoriť subsystém.
Ako posledné môžeme z našej schémy vytvoriť subsystém. Označte všetky bloky okrem bloku Display a cez pravý klik zvoľte Create Subsystem from Selection. Vojdite do subsystemu dvojklikom. Aby sme okrem hodnoty priemeru mali aj informáciu, ktorý senzor je nad čiarou pridáme ďalšie bloky. Blok porovnania Compare To Constant nám vráti logickú 1 ak hodnota signálu presiahne nejakú hodnotu. My budeme považovať, že snímač je nad čiarou, ak hodnota signálu presiahne 50. Blokom Demux rozdelíme signál na jednotlivé žložky pre konkrétne senzory. Ako posledné pripojíme bloky Out (stačí ich nakopírovať už z existujúceho bloku v modely). Aby sme neskôr vedeli, ktorý signál čo znamená, môžeme prepísať popisky pod blokmi out.
V závislosti od váhy v bloku Compare To Constant, môžu dávať viaceré snímače logickú jednotku. Ak by sme chceli zabezpečiť, aby logickú jednotku dával iba jeden snímač (uľahčí nám to návrh počiatočného riadenia), musíme nájsť snímač, ktorý dáva najvyššiu hodnotu signálu. Urobíme to tak, že do schémy pridáme ďalšie dva bloky:
- Simulink - Math Operations - MinMax
- Simulink - Logic and Bit Operations - Relational Operator
Pomocou bloku MinMax nájdeme maximálnu hodnotu zo všetkých signálov a porovnáme ju so signálmi pomocou operátora rovná sa. Výsledkom bude vektor, ktorý bude obsahovať (skoro vždy za ideálnych podmienok) iba jednu logickú jednotku na mieste snímača s maximálnou hodnotou čiernej.
Vytvorené subsystémy použijeme v ďalšom návode, ktorý sa bude zaoberať sledovaním čiary. Uložte si posledné dve verzie snímania ako samostatné modely. Skontrolujte či robot robí pri prechode čiarou snímačmi zľava doprava. Pokiaľ by ste potrebovali, aby hodnoty rástli alebo klesali, je možné otočiť vektor v bloku násobenia. Záleží od poradia zapojenia káblov na analógové piny.
Na zamyslenie
Ako môžeme automatizovať kalibráciu snímačov? Čo tak otočiť robotom na mieste okolo vlastnej osi? V ktorom momente zastať? Skúste tento pohyb vytvoriť ako stav v Stateflowe.