{"id":2255,"date":"2019-02-01T09:28:00","date_gmt":"2019-02-01T09:28:00","guid":{"rendered":"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?page_id=2255"},"modified":"2019-11-30T10:20:05","modified_gmt":"2019-11-30T10:20:05","slug":"joy-radio-2-5","status":"publish","type":"page","link":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?page_id=2255","title":{"rendered":"LF: Line follower"},"content":{"rendered":"<p>Autor: Bartosz Butler<br>Zaawansowanie: zako\u0144czono!<\/p>\n<h1 class=\"entry-title\">Opis algorytmu PD<\/h1>\n<div class=\"entry-meta\"><span class=\"meta-prep meta-prep-author\">Opublikowano<\/span>&nbsp;<a title=\"11:24 am\" href=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?p=1534\" rel=\"bookmark\"><span class=\"entry-date\">Luty 1, 2019<\/span><\/a>,&nbsp;<span class=\"meta-sep\">autor:<\/span>&nbsp;<span class=\"author vcard\"><a class=\"url fn n\" title=\"Zobacz wszystkie wpisy, kt\u00f3rych autorem jest bytler\" href=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?author=24\">bytler<\/a><\/span><\/div>\n<div class=\"entry-content\">\n<p>Z tego wpisu dowiesz si\u0119:<\/p>\n<ul>\n<li>Jak p\u0142ynnie pod\u0105\u017ca\u0107 za lini\u0105?<\/li>\n<li>Jak przetwarza\u0107 sygna\u0142y z czujnik\u00f3w by sterowa\u0107 szybko\u015bci\u0105 poszczeg\u00f3lnych silnik\u00f3w?<\/li>\n<li>Co to jest tzw. \u201ep\u0119tla zwrotna\u201d?<\/li>\n<\/ul>\n<p>A wszystko po to, by oprogramowa\u0107 Line Followera (w skr\u00f3cie LF)!<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1564\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/01\/DSC_6781-300x169.jpg\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" srcset=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/01\/DSC_6781-300x169.jpg 300w, http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/01\/DSC_6781-768x432.jpg 768w, http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/01\/DSC_6781-1024x576.jpg 1024w\" alt=\"\" width=\"300\" height=\"169\"><\/p>\n<p><strong>Regulator PD<\/strong>&nbsp;to \u201cuci\u0119ta\u201d wersja regulatora PID (ang. Proportional-Integral-Derivative). Pos\u0142u\u017cy nam on do p\u0142ynnego sterowania linefollower\u2019em. Regulator ten posiada 3 cz\u0142ony:<br>liniowy (P),<br>ca\u0142kowy (I),<br>r\u00f3\u017cniczkowy (D).<\/p>\n<p><strong>Cz\u0142on P<\/strong>&nbsp;odpowiada za to, jak szybko silniki LF\u2019a b\u0119d\u0105 si\u0119 obraca\u0107 na podstawie po\u0142o\u017cenia linii. Je\u017celi linia b\u0119dzie po prawej stronie czujnika to robot \u201cwie\u201d, \u017ce musi skr\u0119ci\u0107 w tym kierunku i zmniejszy szybko\u015b\u0107 prawego silnika (lub zwi\u0119kszy pr\u0119dko\u015b\u0107 lewego, ale z regu\u0142y lepiej zastosowa\u0107 to pierwsze rozwi\u0105zanie). Jednak sama zale\u017cno\u015b\u0107 liniowa nie wystarcza, \u017ceby p\u0142ynnie pod\u0105\u017ca\u0107 za lini\u0105 (chyba, \u017ce bardzo powoli). \u017beby \u201cprzewidzie\u0107\u201d zmiany w kierunku ruchu i odpowiednio na nie zareagowa\u0107 przydaje si\u0119 nam&nbsp;<strong>cz\u0142on D regulatora<\/strong>. Jest to prosta r\u00f3\u017cnica pomi\u0119dzy poprzedni\u0105 a aktualn\u0105 pozycj\u0105 linii. W przypadku prostej linii r\u00f3\u017cnica b\u0119dzie nieznaczna, a podczas nag\u0142ej zmiany kierunku robot szybciej zmieni szybko\u015b\u0107 silnik\u00f3w.&nbsp;<strong>Cz\u0142on I<\/strong>&nbsp;pomijamy, bo nie jest on zbyt wa\u017cny w przypadku linefollower\u2019\u00f3w (z do\u015bwiadczenia).<\/p>\n<p>Mo\u017ce i jest to na pocz\u0105tek troch\u0119 skomplikowane, ale implementacja jest bardzo prosta i nie wymaga zbyt wiele pisania:<\/p>\n<pre class=\"lang:default decode:true\">error_P = pozycja_linii * KP; \/\/ zale\u017cno\u015b\u0107 liniowa\nerror_D = (pozycja_linii - poprzednia_pozycja_linii) * KD; \/\/ r\u00f3\u017cnica pomi\u0119dzy pomiarami\nError = error_P + error_D; \/\/ suma cz\u0142on\u00f3w regulatora\npoprzednia_pozycja_linii = pozycja_linii;<\/pre>\n<p>Uzyskany w ten spos\u00f3b Error mo\u017cemy bezpo\u015brednio wykorzysta\u0107 do ustawienia pr\u0119dko\u015bci silnik\u00f3w. Wsp\u00f3\u0142czynniki KP i KD okre\u015blaj\u0105 jaki wp\u0142yw maj\u0105 poszczeg\u00f3lne cz\u0142ony na ruch LF\u2019a i b\u0119d\u0105 si\u0119 znacz\u0105co r\u00f3\u017cni\u0107 w zale\u017cno\u015bci od algorytmu wykrywania pozycji linii czy samej budowy robota (np. pozycji czujnika). W\u0142a\u015bnie w konkretnych warto\u015bciach KP, KD&nbsp;<strong>le\u017cy sekret<\/strong>&nbsp;dzia\u0142ania dobrego regulatora PID. \u017beby uzyska\u0107 p\u0142ynny ruch trzeba si\u0119 troch\u0119 \u201cpobawi\u0107\u201d z tymi wsp\u00f3\u0142czynnikami i znale\u017a\u0107 najlepsze warto\u015bci. Mo\u017cna znale\u017a\u0107 wiele metod strojenia takiego regulatora (np. Metoda Zieglera-Nicholsa), jednak w tym przypadku najpro\u015bciej jest to zrobi\u0107 r\u0119cznie czyli metoda pr\u00f3b i b\u0142\u0119d\u00f3w, eksperymentalnie zmieniaj\u0105c KP i KD i sprawdzaj\u0105c na torze jak to wp\u0142ywa na ruch LF.<\/p>\n<p>Na pocz\u0105tku ustawiamy KD = 0, i szukamy najmniejszego KP, \u017ceby robot przy ma\u0142ej pr\u0119dko\u015bci w miar\u0119 dobrze pod\u0105\u017ca\u0142 po prostej linii lub lekkim \u0142uku. Po znalezieniu odpowiedniego KP mo\u017cemy stopniowo zwi\u0119ksza\u0107 wsp\u00f3\u0142czynnik KD i pr\u0119dko\u015b\u0107, do uzyskania p\u0142ynnego ruchu. Jako, \u017ce r\u00f3\u017cnice w pomiarach s\u0105 stosunkowo ma\u0142e w por\u00f3wnaniu do po\u0142o\u017cenia linii, cz\u0119sto nast\u0119puje zale\u017cno\u015b\u0107: KD &gt; KP.<\/p>\n<p><b>Okre\u015blanie pozycji linii, wsp\u00f3lne dzia\u0142anie 5-ciu czujnik\u00f3w<\/b><\/p>\n<p>Jak przy pomocy wielu czujek jednoznacznie okre\u015bli\u0107, gdzie znajduje si\u0119 linia? Ka\u017cda czujka zwraca tylko informacj\u0119 o ilo\u015bci odbitego \u015bwiat\u0142a (warto\u015bci od 0 do 1023). Mo\u017cna by zastosowa\u0107 algorytm kt\u00f3ry wybiera jedn\u0105 pozycj\u0119 z najwi\u0119ksz\u0105 warto\u015bci\u0105 ale prowadzi on tylko do niep\u0142ynnego ruchu. Powinni\u015bmy zastosowa\u0107 bardziej precyzyjny algorytm wykrywania linii ze \u015bredni\u0105 wa\u017con\u0105.<\/p>\n<p>Ka\u017cdemu czujnikowi przypisujemy wagi, na kt\u00f3rych postawie b\u0119dziemy okre\u015bla\u0107 pozycj\u0119 (np. -2000, -1000, 0, 1000, 2000 dla kolejnych czujek). Nast\u0119pnie czytamy warto\u015bci z czujnik\u00f3w, mno\u017cymy je razy wag\u0119 i sumujemy. Na koniec dzielimy otrzyman\u0105 warto\u015b\u0107 przez sum\u0119 warto\u015bci z czujek. W ten spos\u00f3b dok\u0142adn\u0105 informacj\u0119 nawet kiedy linia znajduje si\u0119 na granicy dw\u00f3ch czujnik\u00f3w.<\/p>\n<pre class=\"lang:default decode:true\">pozycja = (cz1*waga1+cz2*waga2+cz3*waga3+cz4*waga4+cz5*waga5)\/(cz1+cz2+cz3+cz4+cz5)<\/pre>\n<p>W przypadku zastosowania wag: -2000, -1000, 0, 1000, 2000 dla kolejnych czujnik\u00f3w, po przeliczeniu \u015bredniej wa\u017conej otrzymamy jedn\u0105 warto\u015b\u0107 od -2000 do 2000 (dla -2000 linia znajduje si\u0119 po lewej stronie, dla 0 \u2013 na \u015brodku, a dla 2000 \u2013 po prawej).<\/p>\n<p><b><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1572 alignnone\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/02\/line_pos-300x161.png\" sizes=\"auto, (max-width: 573px) 100vw, 573px\" srcset=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/02\/line_pos-300x161.png 300w, http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/02\/line_pos.png 627w\" alt=\"\" width=\"573\" height=\"307\"><\/b><\/p>\n<p><b>Sterowanie pr\u0119dko\u015bci\u0105 silnik\u00f3w<\/b><\/p>\n<p>Jak wykorzysta\u0107 wcze\u015bniej otrzymany Error do sterowania pr\u0119dko\u015bci\u0105 silnik\u00f3w? Do ustawienia pr\u0119dko\u015bci pojedynczego silnika u\u017cywamy sygna\u0142u PWN. B\u0119dziemy t\u0105 warto\u015b\u0107 zmienia\u0107 w zale\u017cno\u015bci od uzyskanego Error\u2019a.<\/p>\n<p>Je\u017celi warto\u015b\u0107 Error\u2019a jest ujemna to w naszym przypadku pozycja linii znajduje si\u0119 po lewej stronie LF\u2019a. Aby skorygowa\u0107 ruch b\u0119dziemy zmniejsza\u0107 pr\u0119dko\u015b\u0107 lewego silnika. Analogicznie post\u0119pujemy w przypadku dodatniej warto\u015bci:<\/p>\n<pre class=\"lang:default decode:true\">if(Error &gt; 0){\npwn1=maxSpeed; \/\/maxSpeed to wczesniej ustalona maksymalna warto\u015b\u0107 PWN LF\u2019a\npwn2=maxSpeed-Error;\n} else {\npwn1=maxSpeed+Error;\npwn2=maxSpeed;<\/pre>\n<p>Warto pami\u0119ta\u0107, \u017ce Error mo\u017ce by\u0107 znacznie wi\u0119kszy od warto\u015bci maxSpeed. Je\u017celi warto\u015b\u0107 nowego pwn1 lub pwn2 jest mniejsza od 0 to musimy j\u0105 ustawi\u0107 na 0 (pwn powinien wynosi\u0107 od 0 do 255). Po tych wszystkich operacjach uzyskujemy pwn\u2019y do sterowania silnikami.<\/p>\n<p>M\u00f3j LF w akcji:<\/p>\n<div style=\"width: 640px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-2255-1\" width=\"640\" height=\"360\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/02\/MOV_6780.mp4?_=1\" \/><a href=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/02\/MOV_6780.mp4\">http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/02\/MOV_6780.mp4<\/a><\/video><\/div>\n<div class=\"wp-video\"><span class=\"mejs-offscreen\">Odtwarzacz video<\/span><\/div>\n<p>&nbsp;<\/p>\n<div class=\"wp-video\">\n<div id=\"mep_0\" class=\"mejs-container mejs-container-keyboard-inactive wp-video-shortcode mejs-video\" tabindex=\"0\" role=\"application\" aria-label=\"Odtwarzacz video\">\n<div class=\"mejs-inner\">\n<div class=\"mejs-mediaelement\" style=\"text-align: right;\">&nbsp;<\/div>\n<div class=\"mejs-layers\">\n<div class=\"mejs-overlay mejs-layer mejs-overlay-play\">\n<div class=\"mejs-overlay-button\" tabindex=\"0\" role=\"button\" aria-label=\"Odtw\u00f3rz\" aria-pressed=\"false\">&nbsp;<\/div>\n<\/div>\n<\/div>\n<div class=\"mejs-controls\">\n<div class=\"mejs-button mejs-playpause-button mejs-play\">&nbsp;<\/div>\n<div class=\"mejs-time mejs-currenttime-container\" role=\"timer\" aria-live=\"off\"><span class=\"mejs-currenttime\">00:00<\/span><\/div>\n<div class=\"mejs-time-rail\">&nbsp;<\/div>\n<div class=\"mejs-time mejs-duration-container\"><span class=\"mejs-duration\">00:15<\/span><\/div>\n<div class=\"mejs-button mejs-volume-button mejs-mute\">&nbsp;<\/div>\n<div class=\"mejs-button mejs-fullscreen-button\">&nbsp;<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p style=\"text-align: right;\"><em>(c) Bytler, 2019<\/em><\/p>\n<\/div>\n<p>&nbsp;<\/p>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Autor: Bartosz ButlerZaawansowanie: zako\u0144czono! Opis algorytmu PD Opublikowano&nbsp;Luty 1, 2019,&nbsp;autor:&nbsp;bytler Z tego wpisu dowiesz si\u0119: Jak p\u0142ynnie pod\u0105\u017ca\u0107 za lini\u0105? Jak przetwarza\u0107 sygna\u0142y z czujnik\u00f3w by sterowa\u0107 szybko\u015bci\u0105 poszczeg\u00f3lnych silnik\u00f3w? Co to jest tzw. \u201ep\u0119tla zwrotna\u201d? A wszystko po to, by oprogramowa\u0107 Line Followera (w skr\u00f3cie LF)! Regulator PD&nbsp;to \u201cuci\u0119ta\u201d wersja regulatora PID (ang. Proportional-Integral-Derivative). [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":1564,"parent":1715,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"ngg_post_thumbnail":0,"footnotes":""},"class_list":["post-2255","page","type-page","status-publish","has-post-thumbnail","hentry","post","post-with-thumbnail","post-with-thumbnail-large"],"_links":{"self":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/pages\/2255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2255"}],"version-history":[{"count":3,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/pages\/2255\/revisions"}],"predecessor-version":[{"id":2309,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/pages\/2255\/revisions\/2309"}],"up":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/pages\/1715"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/media\/1564"}],"wp:attachment":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}