Skocz do zawartości

Pitlab

Użytkownicy
  • Zawartość

    47
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    5

Pitlab wygrał w ostatnim dniu 5 kwietnia 2017

Pitlab ma najbardziej lubianą zawartość!

Reputacja

28 Bardzo dobra

O Pitlab

  • Ranga
    3/10

Informacje

  1. Kiepsko jest z czasem po wakacjach, ale wreszcie udało mi się wygospodarować prawie cały dzień na dalszy rozwój robota. W międzyczasie zrobiłem zakupy napędu z przełożeniem 30:1, nowych podzespołów w torze pomiarowym podczerwieni i słupków do mocowania LED-ów 5mm. Zaowocowało to złożeniem brata bliźniaka, bo skoro jest płytka i napęd, to grzech nie dorzucić garści siana i móc porównywać oba rozwiązania. Tak obecnie wygląda rodzeństwo: Sprawy z doborem napędu są wyczerpująco opisane w poprzednich listach, teraz skupmy się na torze pomiarowym odległości. Wcześniej zauważyłem taki problem, że gdy robot zacznie szorować bokiem o ścianę labiryntu jest już po zawodach. Projektując go wymyśliłem że LED będzie na górnej stronie PCB a fotodioda na dolnej, dzięki czemu będzie dodatkowo separowana od zewnętrznych zakłóceń optycznych. Okazuje się to mało istotne, natomiast zbliżenie się do ściany powoduje przerwanie łączności wizualnej między nadajnikiem i odbiornikiem podczerwieni. Mamy wtedy fałszywy pomiar i algorytm centrowania myszy między ściankami korytarza idzie w maliny. Zastosowanie słupka mocującego nadajnik i odbiornik z jednej strony płytki rozwiązuje ten problem, dodatkowo zabezpiecza tor optyczny przed utratą geometrii. Wcześniej jeżeli mocniej stuknęło się w LEDa lub fotodiodę (przy chwytaniu albo podczas upadku ze stołu) elementy mogły się wygiąć i w efekcie nadajnik i odbiornik były ustawione pod innym kątem. Teraz mocowane razem są dwukrotnie stabilniejsze mechanicznie ale przede wszystkim ewentualna zmiana geometrii jest identyczna dla obu elementów. Przy okazji kupiłem na próbę podzespoły, które wydawały się być lepsze. W młodszej myszce jest fotodioda SHF213FA o kącie patrzenia 10°, w starszej była BPV10NF o kącie 20°. LED w nowym zestawie to OSI5LA5201A o kącie 8°, w starszym jest HL-503IR3C-L3 o kącie 20°. Sam układ pomiarowy mam zrobiony jako przetwornik prądu fotodiody na napięcie zrobione na wzmacniaczu operacyjnym: Pomyślałem sobie że zrobię sobie wykres porównawczy, bo oczekiwałem że będzie istotnie lepiej niż w starszym rozwiązaniu. Porównywałem dwa różne tory: Prawy Przedni i Prawy Boczny w nowszej myszy (2) oraz Lewy Przedni i Prawy Boczny w starszej myszy (1). Na osi X jest odległość w mm, na Y napięcie z układu pomiarowego. Wyszło takie coś, że aż zrobiło mi się przykro: Okazuje się że pomiar zaczyna się od ok. 40 mm a wcześniej jest zupełna kicha i to w nowym rozwiązaniu jest nawet gorzej. Dodatkowo o ile dalsza część charakterystyki w starszej myszy była monotonicznie nieliniowa to tutaj jest jeszcze jakieś załamanie po 100 mm. Zacząłem szukać i domyśliłem się że to jest kwestia przesterowania, czyli za dużego wzmocnienia układu pomiarowego. Wylutowałem opornik 47k i wstawiłem potencjometr 100k. Zrobiłem pomiary dla 10k, 20k, 30k i na koniec jeszcze dla 15k bo nie było sensu dalej zwiększać wzmocnienia. Wyszły mi takie charakterystyki: To już zaczyna jakoś wyglądać po ludzku. Okazuje się ze opornik regulujący wzmocnienie powinien mieć wartość rzędu 11-13k. Wcześniej dobierałem wartość oglądając na oscyloskopie odpowiedź na impuls światła LED, tak aby nie przesterować wejścia ADC ponad 3,3V (wzmacniacz zasilany jest napięciem 5V). Ta więc miałem fałszywe kryterium optymalizacji, ale dzięki zrobieniu wykresów sprawa się wyjaśniła. Skoro już dobrnałem do tego miejsca, to może jeszcze pokusić się o linearyzację pomiaru? Regulatory PID są liniowe, wiec zawsze to lepiej jest pracować z liniowymi danymi. Zwykle takie dane daje się zlinearyzować logarytmem naturalnym. Zobaczmy jak to będzie wyglądało w arkuszu: Jest lepiej, ale ciągle daleko od liniowości. Ale zaraz, przecież tutaj są dwa nieliniowe procesy: emisji światła przez LED, oraz detekcji przez fotodiodę. Co by było gdyby to dwukrotnie zlogarytmować? Lepiej? Lepiej! Taki sygnał już spokojnie można podać na regulator. A jeżeli ktoś chce mieć odczyt od razu w milimetrach, to wystarczy przypomnieć sobie z matematyki jak parametry Ax+B wpływają na zachowanie się wykresu. Ale to już później, bo muszę kończyć na dzisiaj.
  2. Ja znów nie znam tego języka (arduino?), ale rysunek dobrze oddaje to co trzeba zrobić czyli uniezależnić generowanie impulsów od sterowania generowaniem. Timer to jest licznik sprzętowy, który odlicza do zadanej przez użytkownika wartości i generuje przerwanie. Czujniki krańcowe masz podpięte pewnie pod wejścia INT0, INT1 i to jest zupełnie inne przerwanie. Ogólnie przerwań jest wiele, są od timerów, UART-ów, PWM, SPI, ADC itd. Nie pamiętam ile jest tego w ATMedze, ale pewnie kilkanaście rodzai z czego pewnie kilka od samych timerów (zwykle od przepełnienia licznika, compare od generowania okresów czasu i capture od pomiaru długości impulsów).
  3. Tego typu sterowanie jest bardzo prymitywne, bo w jednej pętli masz jednocześnie obsługę komunikacji jak i bezpośrednie sterowanie taktem silnika. Prawdopodobnie komunikacja zajmuje odpowiednio więcej czasu niż prosty odczyt stanu wejść i dlatego pętla działa wolniej. Poza tym widzę takie rzeczy że możliwe jest kręcenie silnikiem jednocześnie w obu kierunkach: między if prawo-lewo nie ma else, więc jeżeli oba warunki będą spełnione to silnik będzie szarpał w obie strony. Zdecydowanie źle będzie to wpływało na "kulturę" jego pracy. W pierwszej kolejności do generowania sygnału "step" użył bym timera a w pętli głównej jedynie uaktualniał bym rejestry sterujące timerem i kierunkiem pracy. Po takiej zmianie, sterowanie nie powinno już wpływać na pracę silnika, bo będzie ona zależała wyłącznie od stabilności pracy timera a to można osiągnąć odpowiednio wysokim priorytetem przerwań. Zresztą każde przerwanie, nawet niskopriorytetowe będzie o niebo stabilniejsze od takiej pętli.
  4. W tym tygodniu mam dużo pracy i jeszcze nie udało mi się usiąść do myszy, ale ostatnio zdefiniowałem sobie problem przyspieszenia i dzisiaj zupełnie przypadkiem zapaliła mi się lampka w głowie: przyczepność i wynikający stąd poślizg to sprawa wtórna. To co istotne to II zasada dynamiki: F=m*a Czyli możliwości przyspieszania myszy zależą głównie od jej bezwładności (masy) i siły, czyli momentu silnika dzielonego przez promień koła. Żeby nie mielić na pusto wzorów, spróbujmy policzyć jaki moment powinien mieć silnik napędowy dla zadanego przyspieszenia, albo może lepiej z jakim przyspieszeniem mogę próbować rozpędzać mysz obecnym napędem. Moja mysz bez zasilania waży równiutko 100 g. Na razie jeżdżę z ciężkim pakietem 1600mAh o masie 102 g. Docelowo pakiet, powiedzmy 180mAh waży 20 g. Masa obecna to 202 g, docelowa120 g. Teraz siła. Silnik Pololu z przekładnią 10:1 ma moment 0,029 Nm. Średnica koła to 42 mm, stąd promień to 21 mm. Tak więc maksymalna siła na jednym kole przy pełnym wysterowaniu silnika to: F = M / r = 0,029 / 0,021 = 1,38 N Silniki są 2 więc mamy łączna siłę 2,76 N. Do tego dojdzie tarcie kulki podporowej, więc zaokrąglam siłę do 2,5 N. Teraz przyspieszenie dla obecnego i docelowego rozwiązania. a = F / m a1 = 2,5 / (9,81*0,202) = 1,26 m/s^2 a2 = 2,5 / (9,81*0,120) = 2,12 m/s^2 Gdybym zmienił przekładnię na 30:1 o momencie 0,059 Nm, to miałbym siłę na kole 2,8 N i łączną powiedzmy 5,4 N. Przyspieszenia to odpowiednio 2,73 m/s^2 oraz docelowo 4,59 m/s^2. Tutaj czuć ogień! Dla kompletu informacji warto podać jeszcze prędkości postępowe obu porównywanych napędów: P10:1 ma prędkość obrotową 3000 obr/min => 50 obr/s, więc prędkość liniowa to obrotowa razy obwód: 50 * 2 * Pi * 0,021 = 6,6 m/s P30:1 ma prędkość obrotową 1000 obr/min => 16,67 obr/s, więc prędkość liniowa to obrotowa razy obwód: 16,67 * 2 * Pi * 0,021 = 2,2 m/s Celem konkurencji jest najkrótsza eksploracja i najszybszy przejazd. Zakładając że eksploracja pozwala na jazdę komórka po komórce, więc robot musi rozpędzić się przez połowę komórki a w drugiej części hamować. Mając przyspieszenie i drogę można policzyć czas przejechania komórki dla obu napędów (10:1 i 30:1): t = sqrt( l / a) t10 = sqrt(0,18 / 2,12) = 0,29 s t30 = sqrt(0,18 / 4,59) = 0,20 s Tutaj widać że trzydziestka bije na głowę dziesiątkę. Szybkość przejazdu to trochę bardziej skomplikowana sprawa. Zróbmy to na jakimś przykładzie, tak aby przyjąć ilość odcinków o zadanej długości, np taki labirynt: ma 12 przejazdów po 1 komórce 3 po 2 komórki 4 po 3 5 po 4 2 po 5 1 po 11 komórek 1 po 12 komórek. Teraz trzeba wyliczyć jaki odcinek potrzebny jest do rozpędzenia się do maksymalnej prędkości. Wychodzę ze wzoru na czas rozpędzania do Vmax: t = v / a t10 = 6,6 / 2,12 = 3,11 s t30 = 2,2 / 4,59 = 0,47 s dochodzę do wzoru na drogę jaką pokona rozpędzając się do Vmax l = a * t^2 l10 = 2,12 * 3,11^2 = 20,5 m l30 = 4,59 * 0,47^2 = 1,01 m Już bez większego liczenia widać że napęd 10:1 aby się rozbujać potrzebuje 20 m i zupełnie nie nadaje się do tego typu robota. Napęd 30:1 rozpędzi się na maksa na drodze 6 komórek labiryntu i drugie 6 będzie hamował, więc w tym labiryncie tylko w jednym przejeździe przez chwilę osiągniemy maksymalną prędkość. To pokazuje że warto rozważyć nawet jeszcze wolniejszy napęd dający jeszcze większe przyspieszenie. W międzyczasie zrobiłem arkusz kalkulacyjny do przeliczenia 4 napędów: 10:1, 30:1, 50:1 i 100:1. Odcinki labiryntu podzieliłem na część w której robot się rozpedza i część z jaką jedzie z maksymalną prędkością. Policzyłem czasy pokonywania drogi przyspieszając, czas jazdy z maksymalną prędkością i łączny czas jazdy. Wyszło mi coś takiego: 10:1 = 6,59 + 0 = 6,59 s 30:1 = 4,6 + 0,06 = 4,66 s 50:1 = 2,77 + 4,01 = 6,77 s 100:1 = 0,73 + 18,97 = 19,7 s Wyniki oczywiście będą się zmieniały w zależności od masy i drogi labiryntu, ale dla zastałych warunków wyraźnie widać, który napęd jest optymalny.
  5. Właśnie, w swoim robocie wall-follower miałem identyczny problem, dla danego kp np. robot znajdujący się blisko ściany tak "odbijał", że wjeżdżał w drugą a znajdując się daleko podjeżdżał prawidłowo (lub odwrotnie). Jak myślisz, czy mocniejszy prąd na diodach IR dałby bardziej liniowe odczyty? Nie, nieliniowość wynika z zasady działania tej metody. Po prostu energia wysłana z LED-a rozprasza się tym bardziej im większa odległość, oraz im większy kąt świecenia LED-a. Możemy to narysować jako stożek. Odległość od ściany to wysokość stożka. Jego promień podstawy będzie się zwiększał proporcjonalnie do odległości, ale powierzchnia oświetlana będzie rosła z kwadratem promienia, więc jasność oświetlenia ściany będzie malała proporcjonalnie do jej powierzchni. To właśnie ten kwadrat promienia daje nieliniowość. W pomiarze odległości mamy dwa procesy: wysyłanie a potem detekcja światła. Detekcja jest w zasadzie procesem odwrotnym. Nie wiem dokładnie dlaczego, ale prawdopodobnie ze względu na sprawność procesu detekcji nie odwraca on nieliniowości zjawiska. Podanie większego prądu zwiększy wysłaną energię, więc zwiększy zasięg pomiaru, ale może spowodować wcześniejsze nasycenie detektora przy małych odległościach. Można próbować to rozwiązywać robiąc pomiar dwuetapowy. Raz LED-a zasilamy przez duży opornik i mierzymy krótki dystans, potem zasilamy go przez mniejszy opornik próbując zmierzyć najdalej jak się da. Analiza dwu pomiarów być może da nam wynik w szerszym zakresie niż było by to możliwe przy pojedynczym pomiarze stałym prądem. Warunkiem sensowności używania takiej metody jest nasycanie się detektora na małych odległościach. Linearyzacja na pewno pomaga w procesach sterowania, bo sterowanie jest liniowe. Jeżeli chodzi o materiał to nie sądzę że różnice będą duże. W sieci można znaleźć wykresy działania tej metody dla powierzchni białej i szarej lub nawet czarnej. Biała i szara są minimalnie przesunięte względem siebie. Jeżeli nie chcesz tego zaniedbywać, to proponuję autokalibrację na miejscu. Ustawiasz mysz przodem do ścianki i powoli odjeżdżasz do tyłu zapamiętując pomiary co jakąś odległość. W ten sposób skalibrujesz się w każdych warunkach. Pomiar boczny będzie przecież taki sam jak przedni. Przy okazji wyszło że popełniłem błąd projektowy umieszczając odbiornik pod płytką a nadajnik nad płytką drukowaną. W założeniach była minimalizacja światła padającego na detektor, ale znacznie większym problemem jest to że jeżeli dojadę do ściany, to pomiar przestaje mi działać. Nadajnik i odbiornik muszą być po tej samej stronie i do tego tak blisko siebie jak się da, aby pomiar jeszcze działał przy kontakcie krawędzi myszy ze ścianą. Teraz muszę pomyśleć nad jakąś "inteligencją", aby wykrywać sytuacje gdzie jeden czujnik jest zablokowany. Na szczęście gdy jeden się zatka bo mysz szoruje po ścianie, to drugi pomiar działa poprawnie i to na jego podstawie trzeba wyliczyć pozycję między ścianami i podać do układu regulacji. Dodawanie dwu regulatorów było by połączeniem równoległym a kaskada to połączenie szeregowe. Mam nadzieję że taki odręczny rysunek wyjaśni jak to u mnie działa: Tutaj też są elementy równoległości, np różnica odległości od ścian bocznych jest podana równolegle. Tam zapomniałem jeszcze narysować jeszcze jednego klocka, bo różnica jest niezależnie mnożona przez współczynnik, czyli jest to dodatkowy regulator typu P. Któregoś wieczora zabrałem się za rozpracowywanie hamowania. Rozpędzanie jest łatwe i bazuje na zadeklarowanym przyspieszeniu. Startuję z zerową wartością zadaną regulatora i w każdym obiegu pętli (u mnie 1/100s) powiększam wartość zadaną regulatora o: dv = a * dt; [m/s] = [m/s^2] * [s] Im większe przyjmę przyspieszenie, tym szybciej narośnie mi prędkość. Regulator prędkości powinien być nastrojony ostro, żeby jak najwierniej oddawać kształt prędkości zadanej. Miałem problem z hamowaniem, bo chociaż proces jest analogiczny, ma tylko odwrotny znak, to trzeba wyliczyć kiedy trzeba zacząć hamować. Obliczyłem sobie czas rozpędzania, który musi być równy czasowi hamowania: t = v / a; [s] = [m/s] / [m/s^2] a z czasu doszedłem do drogi hamowania: l = a * t^2; [m] = [m/s^2] * [s^2] Odległość mierzę w ten sposób, że zadaję drogę do pokonania w metrach i w każdym impulsie od zbocza enkodera pomniejszam ją o wyliczoną wartość (obwód koła dzielony przez ilość aktywnych zbocz na obwodzie). Gdy osiągnę zero to wyłączam silniki i jeżeli trzeba to zaczynam następną operację. W kodzie jest warunek że jeżeli droga jest mniejsza niż droga hamowania, to sterowanie silnikami przełącza się na hamowanie odejmując od wartości zadanej a*dt. Problemem jest to że rzeczywistą drogę trzeba trochę skrócić, bo zdarza się że robot na tyle zwolni, że nie jest w stanie dojechać do końca drogi, zwłaszcza gdy zamiast jechać prosto, robot myszkuje między krawędziami pokonując większą drogę. Tak to już jest że życie jest bardziej skomplikowane od prostego modelu. Im bardziej go rozwijamy, tym więcej problemów się pojawia Przy okazji wyliczeń z rozpędzaniem i hamowaniem można obliczyć maksymalną prędkość robota przy zadanym przyspieszeniu podczas eksploracji, gdzie pole widzenia jest max 1 komórkę do przodu, więc droga rozpędzania i hamowania muszą się zmieścić w 18cm. Pytanie teraz jak obliczyć dopuszczalne przyspieszenie? Pewnie potrzebna będzie masa robota żeby policzyć siłę tarcia o podłoże wynikającą z rozpędzania masy. Potrzebny pewnie będzie jakiś współczynnik przyczepności dla danego podłoża. Podłoże jest zmienne, więc trzeba wyznaczać eksperymentalnie. Jaką metodę przyjąć? Na razie próbuję przejechać przez 2 komórki, tak aby zatrzymać się w wyznaczonym punkcie. Jeżeli będzie poślizg, to droga będzie krótsza.
  6. Podstawowe ruchy robota są już jako tako opanowane. Kaskada regulatorów odchylenia działa. Podrzędny regulator prędkości kątowej koryguje odchylenia wynikające z niedoskonałości przekazania napędu. Gdy robot zaczyna odchylać się z niezerową prędkością kątową, to regulator od razu koryguje go, różnicując wysterowanie napędów. Wartość zadana z regulatora prędkości kątowej pochodzi z wyjścia nadrzędnego regulatora PI kąta odchylenia, który jest odpowiedzialny za synchronizację zakrętów i nawrotów. Kąt odchylenia otrzymuję przez całkowanie prędkości kątowej: prędkość * dt (mierzone timerem, nie założone!) Procedurę regulatora mam tak napisaną że zwraca sygnał o wartości w granicach +-100.0f (logiczny odpowiednik +-100%). Teraz jeżeli zadam nawrót o 180° to przy danym wzmocnieniu regulator prawie natychmiast wchodzi na wysterowanie 100. Mnożę to przez zadaną prędkość odchylenia (obecnie 3.6) i otrzymuję wartość zadaną dla regulatora prędkości kątowej odchylenia (obecnie 360°/s). Zmieniając stałą mogę modyfikować prędkość zakręcania. Jeszcze nie jestem pewien gdzie powinna zostać podana korekcja pozycjonowania względem ścianek labiryntu. Na razie mam ją dodawaną do wartości zadanej regulatora prędkości kątowej odchylania (podrzędnego), bo wydawało mi się że on jest szybszy niż nadrzędny. Jednak po przemyśleniu sprawy dochodzę do wniosków że podawanie korekty za regulatorem nadrzędnym powoduje korektę z jego strony. Oczywiście można tak dobrać wzmocnienie żeby to zaczęło działać ale to wydaje się być metodą siłową. Chyba lepiej będzie podać korektę od ścian na regulator nadrzędny. Pierwotnie miałem taki układ że przed każdym ruchem określałem wartość zadaną. Oczywiście była ona zależna od poprzedniego ruchu, więc ewentualne niedokładności sumowały się i za cholerę nie byłem w stanie przejechać kilku zakrętów w labiryncie, bo kąty rozjeżdżały się. Dodałem człon całkujący do regulatora kąta, tak aby minimalizował uchyb ale niewiele pomagało. Dopiero gdy zadawanie kąta wartości zadanej wyrzuciłem przed całą pętlę manewrowania, błędy przestały się kumulować. Przedtem dla przykładowego zakrętu o 90° było tak: wartość_zadana = kąt_bieżący + 90; teraz jest wartość_zadana += 90; Nawet jeżeli zakręt nie wyszedł idealnie, to błąd nie ucieka, tylko zostanie skorygowany w następnych ruchach. Wczoraj gdy już położyłem dzieci spać dodałem zmienną określającą stan ścianek w labiryncie, według metody opisanej na forum (wybaczcie nie pamiętam autora), gdzie bity młodszego półbajtu określają obecność ścianek; 1=północna, 2=wschodnia, 4=południowa, 8=zachodnia. Przyjąłem że labirynt ułożony jest w 1 ćwiartce układu współrzędnych a startujemy zawsze z punktu (0,0). Problem jest tylko z określeniem tego czy zaczynamy jechać wzdłuż osi X czy Y. Rozwiązałem to robiąc pierwszy etap eksploracji labiryntu gdzie jadę do przodu dopóki nie znajdę braku bocznej ścianki. Jeżeli bocznej ścianki nie ma po lewej stronie to znaczy że jadę wzdłuż osi X a jeżeli brak ścianki wykryję po prawej, to znaczy że jadę wzdłuż osi Y. Dalej na razie nie mam jeszcze większej strategii. Teraz jadę do przodu aż do końca. Jeżeli mogę to skręcam w lewo, jeżeli nie to w prawo, jeżeli nie to zakręcam. Zrobiłem sobie prościutki labirynt mieszczący się na starym stole. Zmieściło mi się 4x6 komórek. Pewnie gdy już wszystko wykryję to trzeba będzie analizować gdzie jeszcze można by pojechać i wyznaczać najkrótszą drogę, ale to jeszcze trzeba przemyśleć. Na razie wrzucam filmik z przejazdu po labiryncie. Podłoże to stół na wysoki połysk, ścianki to depron, z jednej strony gładki, z drugiej rowkowany, ale nie jest to zauważalnym problemem.
  7. Wczoraj zrobiłem zawracanie w miejscu, ale kiepsko to wszystko działało. Obrót o 180° zwykle przestrzeliwuje o kilkakanaście stopni. Jazda po prostej szarpie i dosyć mocno myszkuje. Tak być nie może, nie ma sensu ruszać dalej jeżeli podstawy sterowania ledwo dyszą. Zacząłem jeszcze raz stroić regulatory i zauważyłem że podczas jazdy do przodu mam bardzo duży uchyb, rzędu 50%. Ustawiam wartość zadaną regulatora prędkości koła na 1m/s a pomiar pokazuje mi coś w okolicy połowy i mocno się zmienia. Do tego co któryś pomiar prędkości jest zerowy. Zacząłem od pomiarów. Do obliczenia prędkości, mierzę czas między kolejnymi zboczami sygnału enkodera. Niby klasyka, ale ten układ ma feler polegający na tym, że gdy impulsy zatrzymują się, zmierzona prędkość nie jest aktualizowana (obliczenia są w przerwaniu od zbocza impulsu). Więc żeby stojący robot nie raportował ostatnio zmierzonej prędkości zrobiłem taki timeout dekrementowany w osobnym przerwaniu. Po każdym impulsie pomiarowym przeładowuję wartość licznika timeoutu a gdy zejdzie do zera, to zeruję wskazanie prędkości. Czas timeoutu musi być dobrany do pomiaru najmniejszej prędkości. U siebie przyjąłem 0,05m/s. Ponieważ kod obługi timerów był kanibalizowany z innego projektu gdzie mierzyłem prędkości obrotowe rzędu kilkunastu tysięcy obrotów na minutę, więc timeout był za krótki i co jakiś czas zerowało mi pomiar. To była główna przyczyna szarpania przy jeździe prosto. Wcześniej podejrzewałem bicie na oponie. Ponieważ enkoder mam na kole napędowym a nie na wale silnika i ma tylko 12 impulsów na obrót, więc przy okazji włączyłem reakcję na narastające i opadające zbocze sygnały enkodera, co dwukrotnie zwiększa częstotliwość pomiaru i pewnie w jakimś stopniu przekłada się na płynność sterowania. Po takich usprawnieniach dało się jeszcze 4 krotnie zwiększyć wzmocnienie regulatora P prędkości jazdy. Wcześniej robot jeździł z prędkościami od 0,4 do 1,4m/s. Wolniej nie dał rady wysterować silników (za małe wzmocnienie regulatora) a szybciej nie wyhamowywał przed przeszkodą. Po zmianach spokojnie jeździ nawet na 0,2m/s a już mi się wydawało że koniecznie trzeba będzie wymienić napęd, na taki z przełożeniem 30:1. Zauważyłem też że robot rusza z pełną prędkością, pomimo że zrobiłem mu narastanie prędkości z określonym przyspieszeniem (w każdym obiegu pętli zwiększam prędkość o MAX_ACCEL * dt dopóki nie osiągnie zadanej prędkości). Na ostro wystrojonych regulatorach dochodziło do tego, że lekki, piankowy labirynt przesuwał się pod robotem podczas startu! Tutaj okazało się nadpisywałem rozpędzanie przez korektę prędkości od czujników optycznych i od regulacji kąta obrotu. Gdy już to ogarnąłem okazało się że zmiana jednego regulatora wpływa na inne, które modyfikują jego wartość zadaną. To też w końcu podobierałem i teraz robot jeździ po prostym odcinku korytarza do przodu i do tyłu centrując się i wykrywając dojazd do krawędzi. Problem jest tylko z zawracaniem o 180°. Po prostu na wejściu pojawia się tak duży błąd że regulator odpowiada tak dużym sygnałem że PWM sterujący silniki dochodzi do 100%. Trudno jest zrobić precyzyjny obrót na pełnej prędkości, która dochodzi do 5m/s. Tutaj stwierdziłem że trzeba rozbudować regulator odchylenia z pojedynczego regulatora kąta na kaskadę regulatorów: nadrzędny będzie regulator kąta z limiterem na wyjściu a podrzędny będzie regulator prędkości kątowej. Do regulatora kąta będą wchodziły wartości zadane od zakrętów (45°, 90° i 180°) a do regulatora prędkości kątowej wartością zadaną będzie wyjście z regulatora kąta. Tam też prawdopodobnie będę domiksowywał korektę położenia robota z czujników opto.
  8. Dzisiaj miałem kawałek wolnego popołudnia, więc zrobiłem z 0,5m kawałków depronu (taka sztywna pianka izolacyjna) korytko symulujące fragment korytarza w labiryncie. Celem było włączenie pomiaru odległości do algorytmów sterowania trakcją robota. Aby centrować robota względem ścian bocznych odejmuję od siebie sygnały z bocznych czujników i przemnożone przez regulowany współczynnik wzmocnienia dodaję do regulatora kąta odchylenia robota bazującego na żyroskopie. Wartość odczytywana z czujników jest mocno nieliniowa, ale to chyba dobrze gdy robot jest blisko środka to różnice w sygnałach są niewielkie a im bliżej jednej ze ścian to różnica sygnałów rośnie wykładniczo, więc robot szybko ucieka od ściany a potem delikatnie centruje się. Współczynnik wzmocnienia reguluję za pomocą terminala Blueterm. Jedna literka zwiększa wartość, druga zmniejsza i tą metodą dobieram optymalny. Wyraźnie czuć kiedy wzmocnienie jest za małe i kiedy jest za duże. Mam krótką drogę, więc trudno obserwować oscylacje i dostroić tak na tip-top np. metodą Zieglera-Nicholsa, ale nawet tak prosta metoda daje niezłe rezultaty. Druga sprawa to zrobiłem algorytm hamowania przed dotarciem do przeszkody. Tutaj proporcją odległością od przeszkody do braku przeszkody modyfikuję wartość zadaną prędkości robota. Gdy nie ma przeszkody to proporcja jest bliska jedności, gdy się zbliżam proporcja rośnie i zadana prędkość maleje. To działa trochę gorzej i regulacja widoczna jest tylko z jednej strony: za mały współczynnik wzmocnienia powoduje że robot dojeżdża a nawet uderza w ścianę, natomiast zwiększanie ponad pewną wartość nie daje zauważalnych objawów szybszego hamowania. To są szybkie procesy i ciężko jest je obserwować. Tak coś czuję że to hamowanie będzie miało tylko rolę pomocniczą. Podstawa ruchu to będzie zliczanie przejechanej odległości. Co najwyżej będzie korygowane pomiarami odległości, ale tutaj wypadało by je linearyzować. Teraz pisząc pomyślałem że w korytku mogę jeszcze przećwiczyć zawrót o 180°. Na razie "z palca" mogę dać polecenie obrotu o 90° ale to nie działa. Prawdopodobnie korekcja centrująca robota jest zbyt silna. Do zawracania trzeba będzie oprogramować osobny manewr wyłączający czujniki ale to już nie dzisiaj.
  9. Marku, czy to Ty? Na razie najtrudniejsze wydaje się wypracowanie odpowiedniej dynamiki robota. Potrafię go już rozpędzać z zadanym przyspieszeniem, ale jeszcze nie wiem kiedy zacząć hamować. Testowo na podłodze zakręcam już o 90°, ale do zakrętu w labiryncie droga jeszcze daleka. Nie mam bladego pojęcia jak będzie wyglądała jazda po skosie, itd. Samego algorytmu odnalezienia optymalnej drogi specjalnie się nie boję, bo wydaje mi się że wiem jak do tego podejść. Zacznę od "wylewania wody". A gdy już będą różne trasy to spróbuję dla każdego odcinka wyliczyć czas jaki w teorii" zajmie mi jego pokonanie uwzględniając możliwości rozpędzania się na poprzedzających odcinkach. Tą metodą powinienem znaleźć drogę o najkrótszym czasie przejazdu. Czy się nie zaplączę w algorytmach, zobaczymy. W końcu nie po to stary koń robi zabawkę aby się pobawić, tylko czegoś nauczyć. Bardzo chętnie. W tym tygodniu miałem zamiar udać się do castoramy na zakupy, ale jeżeli mogę wypożyczyć to bardzo chętnie. Daj znać kiedy i gdzie mogę po to podjechać. E-mail do mnie to pitlab w domenie pitlab.pl
  10. Jasne, tak zrobię, tylko najpierw muszę ją kupić. To mój pierwszy robot jeżdżący i nie mam jeszcze szuflady "przydasiów". Jestem stary sknera i nie biegam do sklepu po jedną oponę, tylko czekam aż nazbiera się więcej. Może za jakiś czas okaże się że trzeba będzie wymienić silniki na te z przekładnią 30:1? Jak na razie rozwijam wersję z defektami, bo dodatkowe utrudnienia powodują że mam szansę uodpornić się na szerszy zakres problemów. Robot musi działać poprawnie pomimo drobnych problemów. Potem do zawodów będzie można go wychuchać. Gorzej gdyby powstał na wychuchanym sprzęcie a podczas zawodów unieruchomił go drobny problem.
  11. Od dawna nie robiłem żadnego projektu i mam głód na zrobienie czegoś ciekawego. Wybór padł na micromouse. Nigdy nie robiłem robotów jeżdżących, więc jest szansa na wypracowanie doświadczenia w tym zakresie. Schemat robota oparłem o inny projekt bazujący na kontrolerze LPC1768FBD100. Kontroler mógłby być mniejszy, ale akurat taki miałem. Podstawową zaletą ARMa w porównaniu z ATMegą jest możliwość debugowania przez JTAG. Drastycznie ułatwia to znajdowanie błędów w programie. Zasoby sprzętowe i moc obliczeniowa sprawiają, że nawet do drobnych projektów jak micromouse nie warto sięgać po nic mniejszego. Ogólne założenia: Czujniki Nie robiłem porównań, ale wydaje mi się że pomiar odległości robiony na fototranzystorach ma dosyć małą dynamikę w funkcji oświetlenia, tzn. szybko się nasyca, dlatego pomiar oparłem na fotodiodach pracujących ze wzmacniaczem operacyjnym w układzie konwertera prąd na napięcie. Wybrałem LEDy LIRED5B-940-H i fotodiody BPV10NF pracujące w paśmie 940nm. LED-y są na górnej warstwie, fotodiody na spodzie, tak aby jak najbardziej chronić je przez zewnętrznym światłem. Fotodioda ma spory kąt, bo aż 20°, LED 10° ale nic rozsądniejszego na razie nie udało mi się znaleźć. Jeszcze nie jeżdżę w labiryncie, ale zakres pomiarowy to ok. 12cm. Nie wiedziałem czego mam się spodziewać, więc dałem łącznie 6 zestawów: boki, 2x przód i 2x po skosie. Sknociłem kierując skośne na krzyż (prawy świeci a lewo i v.v.). Przy takim zasięgu pewnie będą nieużyteczne. Z czujników pomocniczych jest jeszcze żyroskop ITG-3200 i magnetometr MMC310MR pomyślany jako kompensacja dryftu żyroskopu. Komunikacja Wstawiłem moduł bluetooth, tak aby dało się sterować i debugować terminalem na telefonie. Działa całkiem fajnie. Testowo wstawiłem na płytkę gniazdo karty micro SD podpięte do SPI kontrolera. Tak działający loger mam oprogramowany w podobnym projekcie, więc tutaj będzie można to wykorzystać, gdyby okazało się że bluetooth nie zapewnia odpowiedniej wydajności transmisji danych. Przewidziałem też jeden przycisk, gdyby okazało się że nie można używać łączności BT. Komplet dopełnia LED RGB do sygnalizacji statusu robota. Eksperymentalnie wyprowadziłem też wyjście DAC na wolny wzmacniacz operacyjny, gdyby okazało się że potrzebne było by generowanie komunikatów akustycznych. Mam jeden projekt gadający ludzkim głosem, więc jeżeli będzie trzeba i nadmiar czasu to jest baza do eksperymentów. Napęd Użyłem silników Pololu z przekładnią 10:1. Pierwsze próby pokazują że lepsze byłby z przekładnią 30:1. Ten rozwija prędkości do 6 m/s i ma dosyć mały moment ale daje radę. Jako enkodery użyłem sprzedawane w komplecie z silnikiem i kołem o średnicy 43mm. Za trzeci punkt podparcia robi plastikowa kulka, też gotowiec Pololu. Zasilanie Pakiet LiPo 2S. Przymierzałem się do LiFePO4 w rozmiarze 18650, ale nijak tego nie mogłem wpasować w konstrukcję. Docelowego pakietu jeszcze nie mam, testowo używam 1600mAh. Napęd jest zasilany bezpośrednio z pakietu. Część 5V elektroniki zasilana z przetwornicy step down na L5972D. Część cyfrowa 3,3V zasilana z liniowego MCP1703 zasilanego z 5V. Tak robot wygląda dzisiaj: Jeżeli chodzi o stan oprogramowania to steruję już silnikami, czytam enkodery, mam zapięty człon regulatora P z PID na stabilizacji prędkości każdego z kół. Jest też rozpędzanie robota poprzez sterowanie wartością zadaną regulatora. Definiuję dopuszczalne przyspieszenie i w każdym obiegu pętli powiększam prędkość zadaną o: a*dt dotąd aż dojdę do zadanej prędkości. Jeszcze nie potrafię wyliczyć kiedy rozpocząć hamowanie. Mam odczyt z żyroskopu i całkowanie prędkości kątowej tak aby uzyskać kąt. Dzisiaj zapiąłem kolejny PID (na razie PI) do sterowania zakręcaniem o zadany kąt. PID nie jest tu najlepszy, bo pod koniec zakrętu gdzie jest mały błąd korekcja PIDa się zmniejsza. Na razie testuję to tak że podając znak z terminala robor wykonuje zakręt w prawo lub lewo o 90°. Przez chwilę miałem błąd i przesterowywałem regulator to robot zakręcał ładnie. Po poprawce nie dociąga końcówek. Trzeba będzie to jakoś inaczej rozwiązać. Działa też kalibracja żyroskopu robiona po starcie. Mimo to kąt zauważalnie płynie. Było trochę problemów z jazda prosto, bo jeden silnik kręci się wolniej i do tego ma bicie na połówce opony (krzywo złożona forma odlewnicza). Układ w otwartej pętli sterowania kręcił się w kółko. Z PIDem trochę skręca, z kolejnym PIDem na żyroskopie już jest całkiem nieźle. Trzeba wypracować nastawy regulatorów i może będzie jeździł prosto Magnetometr już potrafię odczytać. Trzeba jeszcze go skalibrować i wyliczać kurs magnetyczny, tak aby można było go spiąć filtrem komplementarnym z żyroskopem, tak aby kąt nie płynął. Na razie mam tylko tyle. W najbliższym czasie będę próbował rozwinać sekwencer ruchów robota, tak aby mógł płynnie wykonać operację typu jedź 2 komórki prosto, skręć 90° w lewo, jedną prosto i zawróć o 180° w prawo. Czeka mnie też zrobienie labiryntu, pewnie 8x8 i próby ustawienia robota przy wykorzystaniu czujników odległości.
  12. Informacja może nie do końca pokrywa się z tematyką forum, ale warto wiedzieć: W dniach 19-23 marca 2013 roku w Muzeum Techniki mieszczącym się w PKiN w Warszawie odbędzie się Drugi Przegląd Bezzałogowych Systemów Latających. Będziemy wystawiać tam nasze OSD, Autopilota, Stację Naziemną oraz SkyAssistanta. Zapraszamy do odwiedzenia naszego stoiska.
  13. Dzisiaj wreszcie wgrałem kod na komputer w quadrokopterze i wylatałem jeden pakiet. Różnica w działaniu jest wyraźna. Przedtem gdy polegałem na danych z czujników filtrowanych dolnoprzepustowo, nie mogłem sobie poradzić z utrzymaniem wysokości. Oscylacje rzędu 2-3m to był normalka. Po pracy śmigieł słychać było jak pracuje człon różniczkujący szarpiąc silnikami. Teraz regulatory PID nie są jeszcze dostrojone do nowych warunków, ale na dzień dobry w ogóle nie słychać jazgotu śmigieł, tylko jednostajny szum. Sygnał wejściowy jest dużo gładszy, to i sygnał wyjściowy z członu różniczkującego też jest gładszy i nie katuje silników ciagłymi zmianami prędkości obrotwej. Na początek podpiąłem 2 potencjometry w aparaturze pod współczynniki Kp członów P regulatora wysokości i regulatora prędkości pionowej - taki sposób regulacji on-line. Na obydwu podniosłem wzmocnienie dwukrotnie i nadal zachowuje się stabilnie. To akurat jest trochę podejrzane, bo niedawno rozszerzałem możliwości sterowania z jednego kanału na 2 i być może coś skopałem. Sprawa do weryfikacji. Tak wygląda fragment wykresu regulacji wysokości. Na górze pomarańczowa linia to wartość zadana (drążek aparatury), ciemnomiebieskie to wysokość z kalmana, jasnoniebieskie to wysokość z czujnika. Wszystko wyskalowane w metrach Na dole żółta linie to wyjście regulatora PID a linie w kolorach R, G, B to składowe P, I oraz D Jest wyraźny postęp chociaż jeszcze nie ma się czym chwalić dopóki nie nastroję regulatorów. Na razie podstawowy szum spadł od ok. 1 m, ale jeszcze praktycznie nie działa człon różniczkujący (niebieska linia na dolnym wykresie). Trzeba podkręcić czas różniczkowania, wtedy kopter będzie sztywniej trzymał się wartości zadanej. Na logach z koptera niewiele widać, bo miałem ustawione logowanie na 15 Hz. To jednak dosyć mało aby widzieć problemy z szumem. Teraz zmniejszyłem ilość logowanych danych i podniosłem częstotliwość do 25 Hz to w następnym locie będzie widać ciut więcej. To że sygnał z czujników mocno pokrywa się z sygnałem z kalmana to w dużej mierze kwestia działania samego logera, który uśrednia dane. Dane wchodzą na 200 Hz a wychodzą na 15 Hz czyli na wykresie są uśrednione 13,3 raza. Chyba wyrzucę to uśrednianie bo na obecnym etapie rozwoju więcej psuje niż pomaga a zajmuje sporo czasu procesora. Ja wymiękam przy takich obliczeniach Dzisiaj przed lotami trochę posiedziałem i zmieniałem parametry szumu poszczególnych czujników aby znaleźć zadowalające wartości współczynników kalmana. Z danych zbliżonych do rzeczywistych współczynnik kalmana dla korekcji wysokości wychodził dużo niższy niż dla prędkości. algorytm chciał bardziej polegać na sygnale z wariometru niż z wysokościomierza. Zrobiłem serię pomiarów aby znaleźć zależności między parametrami szumu a finalnymi współczynnikami kalmana. Wyszła mi taka tabelka: Modyfikowałem dotąd aż uzyskałem współczynnik dla wysokości (K00) trochę większy niż dla prędkości (K11). Proporcje między nimi są już zachowane. Proporcje między korekcją a predykcją zmieniam modyfikując szum akcelerometru. Widać że wartości szumu nie mają nic wspólnego z warunkami rzeczywistymi, są kompletnie nieintuicyjne (0,01 i 2,0). Tak wiec ten model nie jest rzeczywisty ale działa i w sumie tyle wystarczy. O rety! Ja już gonię na oparach wolnego czasu a tu do implementacji filtr na macierzy 3x3 Spróbuję to zakodować, ale potrzebuję kilku dni, bo już teraz mam trochę poprawek do uwzględnienia a żeby móc to porównać warto dopiąć na ostatni guzik.
  14. Świetna robota! Możliwość analizy rzeczywistych danych w programie jest wielkim przełomem w pracy nad algorytmami, tylko ze wstydem muszę przyznać że nie potrafię wczytać danych. Próbowałem podawać pełną ścieżkę do pliku na swoim komputerze, ale program wyrzuca błąd dla funkcji importdata. Uruchamiam to na stronie: http://www.verbosus.com/octavus.html. Przejrzałem dokumentacje octave ale tam nie ma takiego słowa kluczowego. Czy to jest Twoja własna funkcja? Prosiłbym o kilka słów komentarza jak się tym posługiwać. Czyli jest znacznie mniej mnożenia przez krok czasu dt niż w moim przykładzie. To jest mała wartość, u mnie w okolicy 0,005s, więc macierz kowariancji finalnie przybiera większe wartości. Tutaj nie ma dt^2, więc wartości macierzy kowariancji są większe. W swoich testach też zaobserwowałem że zdefiniowanie większego szumu daje lepsze wyniki, tylko u mnie potrafiło się wykrzaczyć przy zbyt dużym szumie. Spróbuję jeszcze tak jak Ty wyrzucić elementy macierzy poza główna przekątną. Dodane po dłuższej chwili. Ze wstydu ze osoby trzecie więcej pracują nad moim problemem niż ja sam, wgrałem kod (ten po dzisiejszych poprawkach z okrojonymi macierzami kowariancji procesu i pomiaru) na kopter i przedmuchałem go w biurze. Jako punkt odniesienia pomiar z wyłączonymi silnikami Następnie z włączonymi silnikami pracującymi na prędkości znamionowej, takiej gdzie ciąg śmigieł równoważy masę koptera. Byłem przekonany że będę miał znacznie większy szum na akcelerometrach, ale widocznie po przejściu przez obliczenia IMU przyspieszenia też się filtrują. To dobrze, bo nie ma dużego problemu z szumem procesu. Być może jest to efekt filtrowania drgań spowodowany trzymaniem koptera w ręku. Starałem się trzymać za elastycznie mocowany pakiet napędowy, ale mimo wszystko drgania mogły być częściowo stłumione. Pełną prawdę poznam w rzeczywistym locie. Jest za to spory szum wysokości i wariometru. To mogę jeszcze próbować zmniejszyć filtrem mechanicznym z gąbki założonej na czujnik. Po uproszczeniu macierzy kowariancji zmieniły się dwie rzeczy: - Współczynniki kalmana są teraz stałe. Wcześniej gdy wyświetlałem je na wykresie to widać że się zmieniały a teraz stoją w miejscu (teraz wyrzuciłem je z wykresu aby lepiej było widać dane pomiarowe). To pewnie efekt zer poza główną przekątną w macierzy kowariancji - Teraz estymata wysokości jest znacznie gładsza i o to właśnie chodzi. Wygląda na to że kod jest gotowy do oblatania. Odłożę to na jutro, bo dzisiaj jestem mocno zajęty i jeszcze nie wydobrzałem po ostatniej chorobie. Swoją drogą jutro ma być cieplej.
  15. Nie nadaje się do wario w moim module, bo to jest wariometr na wzmacniaczu operacyjnym i wymaga sygnału analogowego. Wariometr można zrobić z dowolnego czujnika ciśnienia, tylko jego jakość będzie zależała od rozdzielczości pomiaru wysokości. Jeżeli czujnik ma rozdzielczość rzędu 1m to wariometr zrobiony z niego będzie lichy. Są już czujniki o rozdzielczości kilku cm np MS5611 i z czyś takim można już wiele zrobić.
×
×
  • Utwórz nowe...