Wizualizacja Danych Sensorycznych Wizualizacja sensorów robota

Transkrypt

Wizualizacja Danych Sensorycznych Wizualizacja sensorów robota
Wizualizacja Danych Sensorycznych
Wizualizacja sensorów robota klasy line follower
Dawid Powązka 163054
13 czerwca 2010
1
Spis treści
1 Opis problemu.
3
2 Harmonogram prac.
3
3 Komunikacja.
3.1 Mikrokontroler. . . . .
3.2 Aplikacja. . . . . . . .
3.3 Suma kontrolna CRC.
3.4 Realizacja sprzętowa. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
4
5
6
7
4 Wizualizacja czujników.
7
5 Rysowanie trasy robota.
5.1 Napotkane problemy. . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 Zrealizowana koncepcja. . . . . . . . . . . . . . . . . . . . . . . .
7
8
8
6 Interfejs graficzny aplikacji
8
7 Diagram klas.
9
8 Schemat przepływu.
9
9 Testy oraz uzyskane wyniki.
9
10 Wnioski.
11
2
1
Opis problemu.
Głównym zadaniem projektu jest zaprojektowanie aplikacji graficznej, która w
jednoznaczny i przejrzysty sposób będzie obrazowała stan czujników robota line
follower. Roboty tego typu mają za zadanie poruszanie się po trasie wyznaczonej
poprzez linie. Na świecie rozgrywane są zawody takich robotów, gdzie startują
różnorodne konstrukcje, których sterowanie odbywa się na podstawie odpowiednich czujników. Roboty te muszą posiadać sensory koloru, które umożliwiają
określenie położenia linii względem robota. Najczęściej stosowane są czarne linie, umieszczone na białym tle. W zależności o konstrukcji i konwencji roboty
takie posiadają różną liczbę takich czujników. Zbudowany przeze mnie robot posiada 5 czujników zbudowanych za pomocą reflekcyjnych czujników odbiciowych
CNY70. Za pomocą odpowiednich rezystorów czujniki zostały skalibrowane tak,
że gdy znajdują się nad czarną linią uzyskujemy stan logicznej 1, a gdy znajdują się nad białym obszarem otrzymujemy logiczne 0. Wizualizacja sprowadza
się zatem do pokazywania dwóch stanów czujników. Ponad to, wykorzystywany
do testów robot jest platformą mobilną klasy 2.0, co znaczy, że posiada dwa
niezależnie napędzane koła. Aplikacja powinna wyświetlać prędkości silników
tego robota. Dodatkową udostępnianą funkcją będzie możliwość wyrysowywania trasy przebytej przez robota, jeśli będzie to możliwe.
2
Harmonogram prac.
• 1 tydzień: Zapoznanie się ze środowiskiem Qt4.
• 1 tydzień: Projekt graficznego wyglądu aplikacji.
• 1 tydzień: Ostateczny wybór elementów graficznych oraz ich rozmieszczenia w aplikacji. Gotowy szablon aplikacji.
• 1 tydzień: Utworzenie połączeń oraz reakcji pomiędzy poszczególnymi elementami.
• Punkt kontrolny: Przedstawienie szkieletowej aplikacji, która symuluje wybrane reakcje na żądania ze strony użytkownika, jak i
symuluje pracę czujników.
• 1 tydzień: Rozwój modułu komunikacji aplikacji z robotem poprzez port szeregowy.
• 1 tydzień: Wstępne testy komunikacji.
• 1 tydzień: Weryfikacja i poprawa ewentualnych błędów w komunikacji aplikacji z robotem. Testy ostateczne.
• Kamień milowy: działająca aplikacja, poprawnie komunikująca się z robotem.
• 1 tydzień: Testy działania aplikacji na prawdziwym robocie.
• 1 tydzień: Rozwijanie algorytmu odtwarzającego trasę, którą przejechał
robot, na podstawie danych z czujników.
3
• 1 tydzień: Testy algorytmu.
Ostatnie cztery punkty harmonogramu zostały przesunięte w czasie o mniej
więcej 1 tydzień. Spowodowane to było opoźnieniami w pracach na robotem,
który powstawał na zaliczenie innego projektu.
3
Komunikacja.
Aby możliwa była wizualizacja pracy czujników należało nawiązać nić porozumienia z robotem. Postanowiono użyć komunikacji przez port szeregowy oraz
standardu rs232. Jest to standard rozpowszechniony oraz wiele mikrokontrolerów ma wbudowane moduły do transmisji asynchronicznej. Poniżej przedstawione są przyjęte przeze mnie parametry transmisji, które dla obu urządzeń
muszą zostać ustawione jednakowe:
• Prędkość transmisji: 2400 bps.
• Liczba bitów danych: 8 bitów.
• Parzystość: wyłączona.
• Kontrola przepływu: wyłączona.
• Bity stopu: 1 bit stopu.
Poniższe podrozdziały opisują rozwiązania komunikacyjne po stronie mikrokontrolera oraz aplikacji.
3.1
Mikrokontroler.
Mikrokontrolerem sterującym robotem jest Atmega8. Posiada on moduł USART
do synchronicznej i asynchronicznej transmisji szeregowej. Skonfigurowany on
został w drugim trybie pracy. Kod poniżej przedstawia inicjalizację modułu:
/* Ustawianie prędkości*/
UBRRH = (unsigned char)(UART_CONST >>8);
UBRRL = (unsigned char)UART_CONST ;
UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);//załączenie odbiornika i nadajnika, włączenie prze
Niekoniecznym jest ustawianie wymienionych wyżej parametrów transmisji,
ponieważ są one przyjmowane jako domyślne. 16- bitowy rejestr UBBR zawiera
informacje o prędkości transmisji. Należy wpisać tutaj wartość wyliczoną na
podstawie częstotliwości zegara mikrokontrolera F CPU oraz żądanej prędkości
F CP U
transmisji według wzoru 16ulBAU
D −1. Mikrokontroler wysyła dane o czujnikach
oraz silnikach na zewnętrzne żądanie. W funkcji obsługi przerwania wysyłane
są 4 bajty danych.
• 1 bajt: sensory.
• 2 bajt: silnik lewy.
• 3 bajt: silnik prawy.
• 4 bajt: suma kontrolna CRC.
4
Poniższy fragment kodu przedstawia obsługę wysyłania.
ISR(USART_RXC_vect)
{
UDR;
unsigned char CRC=0;
// odczytanie CRC
CRC= Tablica_CRC[CRC^(SENSORY&0b0011111)];
CRC= Tablica_CRC[CRC^LEWY];
CRC= Tablica_CRC[CRC^PRAWY];
// Wysyłanie
UART_send_number(SENSORY&0b0011111);
UART_send_number(LEWY);
UART_send_number(PRAWY);
UART_send_number(CRC);
}
Funkcje wysyłające pochodzą z modułu uart.h, który został napisany na
potrzeby innego projektu. Dokumentacja do tego modułu została dołączona
do tego sprawozdania. Zastosowane wyrażenie (SEN SORY &0b0011111) ma na
celu eliminację dwóch najstarszych bitów, do których nie są podpięte czujniki.
3.2
Aplikacja.
W aplikacji do obsługi portu szeregowego użyto modułu MenageSerialPort,
który bezpośrednio korzysta z platformy QextSerialPort. Obie platformy są na
licencji GPL. W bardzo prosty sposób pomagają obsługiwać port szeregowy.
Zaletą tych modułów jest możliwość instalowania na systemach Windowsowych
oraz Posixsowych. Przy ustawianiu i korzystaniu z tej biblioteki przydatna była
pozycja [1] w bibliografii.
Bardzo ważnym elementem jest odpowiednie skonfigurowanie portu. Wykorzystywana biblioteka umożliwia skonfigurowanie portu w dość łatwy sposób.
Poniższy kod przedstawia inicjalizację parametrów portu.
serialPort->setPort(port); //Port
serialPort->setBaudRate(BAUD2400); //BaudRate
serialPort->setDataBits(DATA_8); //DataBits
serialPort->setParity(PAR_NONE); //Parity
serialPort->setStopBits(STOP_1); //StopBits
serialPort->setFlowControl(FLOW_OFF); //FlowControl
Aplikacja zgłasza żądanie do mikrokntrolera o wysłanie ramki z danymi. W
tym celu wysyła ona jeden bajt. Bajt ten zawiera znak ’1’, jednakże mógłby
to być dowolny znak lub liczba 8 bitowa. Mikrokontroler w żaden sposób nie
wykorzystuje przesyłanych danych. Służą one jedynie do wyzwolenia funkcji
obsługującej przerwania od zakończenia odbioru danych. W tym punkcie nie
jest wyliczana suma kontrolna CRC. Dane mogą ulec zmianie. Nie będzie to
miało wpływu na działanie programu.
Odbieranie danych odbywa się na zasadzie przerwania. Dzięki temu nie musimy ciągle świadomie sprawdzać portu. Odbywa się to w klasie MenageSerialPort w wątku. Sprawdzanie polega na czekaniu aż w buforze będą minimum 4
5
bajty danych. Dopiero wtedy dane są ściągane z bufora. Wysyłany jest wtedy
sygnał o otrzymaniu nowych danych, który odbiera funkcja realizująca dalsze
funkcje. Bezpośrednio po odbiorze sprawdzana jest suma kontrolna CRC. Jeśli
CRC się zgadza z tym wysłanym przez mikrokontroler wykonywane są dalsze
operacje. Jeśli CRC się różni nie podejmowana jest żadna akcja. W ogółu przypadków urządzenie zewnętrzne proszone jest o ponownie przesłanie paczki z
danymi. W naszym przypadku nie jest to odpowiednie rozwiązanie. Po pierwsze dane, które są wysyłane ulegają szybkim zmianą. Druga rzecz związana jest
z ograniczeniami czasowymi. Nawet ponownie wysłanie tych samych danych
sprawi, że staną się one bezużyteczne. Robot jest w ciągłym ruchu, także zdąży
się już przemieścić do przodu.
3.3
Suma kontrolna CRC.
Do kontroli poprawności uzyskiwanych danych z mikrokontrolera zastosowano
sumę kontrolną CRC. CRC jest to cykliczna suma kontrolna, która jest bardziej
niezawodna od zwykłej sumy kontrolnej. CRC otrzymuje się poprzez dzielenie
liczby binarnej przez wcześniej określoną wartość. W swoim przykładzie wykorzystałem CRC 8-bitowe oraz specjalnie wygenerowaną tablicę z wartościami
CRC. Tworzenie CRC uzyskuje się odczytując odpowiednie liczby z tej tablicy.
Indeks z którego należy odczytać daną tworzy się za pomocą operacji XOR bajtu
CRC z bajtem danych. Przykład poniżej przedstawia przykładowe liczenie CRC
dla 3 danych:
unsigned char CRC=0;
CRC = Tablica_CRC[CRC^dane1];
CRC = Tablica_CRC[CRC^dane2];
CRC = Tablica_CRC[CRC^dane2];
Tablica poniżej zestawia wyliczone wartości sumy kontrolnej CRC, która
została użyta w tym projekcie.
unsigned char Tablica_CRC[256]=
{ 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
};
6
3.4
Realizacja sprzętowa.
Komunikacja pomiędzy robotem a komputerem w pierwszym zamyśle miała się
odbywać przez port szeregowy komputera. Szybko zrezygnowano z tego pomysłu, ponieważ kable są z reguły krótkie oraz dosyć ciężkie. Z pewnością uniemożliwiło to by swobodne poruszanie się lekkiego robota. Postanowiono zakupić
specjalne moduły do transmisji radiowej. Pierwszy moduł zamontowany został
na robocie. Posiada on bezpośrednie wyprowadzenia linii RXD i TXD, które
zostały bezpośrednio podłączone do mikrokontrolera. Moduł po stronie komputera podpinany jest do portu USB, jednakże na komputerze emulowany jest
wirtualny port szeregowy. W związku z tym komunikacja odbywa się w taki sam
sposób jak przez port szeregowy. W testach z wykorzystaniem terminala komunikacja działa w bardzo zadowalający sposób. Jednakże poprzez wykorzystanie projektowanej aplikacji nie udało się nawiązać bezprzewodowej komunikacji.
Moduł nie odpowiadał. Prawdopodobnie wystąpił jakiś błąd natury sprzętowej.
Biorąc uwagę na względy czasowe wykonania projektu, wykorzystano jeszcze
jeden sposób. Wyprowadzenia RXD i TXD modułu konwertującego standard
USB na RS232, opratym na chipie FTDI, przedłużono za pomocą przewodów.
Rozwiązanie to zaoszczędziło dużo czasu i pozwoliło na dalszą realizację zadania.
4
Wizualizacja czujników.
Głównym zadaniem aplikacji jest wizualizacja czujników koloru robota line follower. Aby tego dokonać pobierane są dane z robota w sposób opisany w poprzednim rozdziale. Funkcja wysyłająca wywoływana jest co pewien określony przez
użytkownika czas. Realizowane jest z wykorzystaniem klasy QTimer. Co określony interwał czasu uruchamiana jest funkcja Refresh. Wtedy wysyłane jest żądanie o dane do mikrokontrolera. Dane odbierane w funkcji new dataReceived są
odpowiednio przetwarzane. Jeśli dane są poprawne, czyli suma kontrolna CRC
się zgadza obliczane są odpowiednie stany czujników koloru z liczby zawartej
w 1 przesłanym bajcie. Liczba ta określa stan portu do którego podłączone są
czujniki. Stan czujnika znajduje się na odpowiednim bicie. Odczytywany jest
za pomocą koniunkcji otrzymanej liczby z liczbą, która określa pozycję danego
sensora. Jest to 1 przesunięta o odpowiednią liczbę bitów w lewo. Przykładowo
dla czujnika trzeciego, czyli środkowego, wyrażenie będzie miało postać: value
& 4. Wyrażenie takie przyjmuje tylko wartości 1 lub 0. Drugi i trzeci przesłany
bajt oznacza wypełnienie PWMa sterującego silnikami. Są to liczby 8- bitowe.
Zamieniane są one na procentowe wypełnienie. Dane uzyskiwane z trzech pierwszych bajtów zapisywane są do klasy Dane. Taka paczka zostaje dodana do listy
i poddana przetwarzaniu w celu uzyskania drogi. Dokładnie jest to omówione w
rozdziale 5.
5
Rysowanie trasy robota.
Dodatkową funkcją udostępnianą użytkownika jest możliwość wyrysowania drogi,
którą przebył robot na podstawie danych uzyskiwanych z czujników i silników.
Nie jest to zadanie łatwe i jednoznaczne. W dużym stopniu zależy od algorytmu
sterowania robota. Poniższe podrozdziały opisują problemy napotkane przy realizacji tego zadania i opis zrealizowanego rysowania.
7
5.1
Napotkane problemy.
Początkowym założeniem było zrealizowanie rysowania całej drogi przebytej
przez robota w formie małej mapy. Niestety takiego podejścia nie udało się
uzyskać z powodów powstałych niepewności i niedokładności. Pierwszym elementem jest sterowanie robota, które realizuje bardzo prymitywny algorytm.
Skutkuje to częstym skanowaniem linii oraz częstym skręcaniem. Uzyskujemy
bardzo zróżnicowane odczyty z których w jednoznaczny sposób nie można wywnioskować aktualnego ruchu robota. Istotny problem był przy rysowaniu skręcania. Nie posiadamy informacji o ile tak naprawdę zrotował robot. W takim
wypadku rysowana droga nie odzwierciedlała w żaden sposób tej rzeczywistej.
Powstawały zapętlenia i przekłamania. Pewnym rozwiązaniem tej sytuacji byłoby zastosowanie enkoderów oraz mierzenie drogi przebytej przez każde z kół.
Na podstawie tych danych moglibyśmy wywnioskować o jak duży kąt zrotował
robot. Rozwiązanie to miało bardzo wiele niedociągnięć wynikających z wielkiego zróżnicowania pomiarów także zrezygnowano z tego pomysłu.
5.2
Zrealizowana koncepcja.
Druga bardziej uproszczona koncepcja pozwala na wyrysowywanie pojedynczych ”kawałków”drogi robota. Wyrysowywany jest odcinek prosty, prawy lub
lewy łuk świadczący o skręcaniu. W związku z bardzo chaotycznymi odczytami,
postanowiłem, że próbki danych od sensorów będą zapisywane i następnie na
podstawie większej ilości danych, będzie następowało odtworzenie ruchu robota.
Ilość tych próbek może ustalać bezpośrednio sam użytkownik. Algorytm działania jest przedstawiony poniżej:
• Obliczana jest pozycja linii na podstawie jednej paczki danych.
• Obliczana jest różnica pomiędzy prędkościami silników.
• Na podstawie danych oceniany jest ruch robota.
• Najbardziej powtarzający się ruch jest zapisywany na listę dopasowań.
• Uruchamiane jest rysowanie.
Rysowanie zostało zaimplementowane na bazie klasy OknoZRysunkiem, znajdującej się w materiałach do wykładu [2]. Klasa ta została odpowiednio zmodyfikowana. Całość rysowania odbywa się w funkcji paintEvent. Z listy dopasowań
ściągany jest pierwszy element oraz wyrysowywany jest odpowiedni kształt. Prosta i łuki są generowane z wcześniej ustalonych punktów.
6
Interfejs graficzny aplikacji
Rysunek 1 przedstawia interfejs graficzny aplikacji.
Interfejs graficzny został podzielony na pomniejsze sekcje za pomocą grupowania kontrolek. Menu Połączenie służy do wybrania portu na którym ma
się odbywać komunikacja oraz przyciski połączenia i rozłączenia. Poniżej okno
Komunikat służy do wyświetlania użytkownikowi informacji o stanie i błędach
połączenia. Dodatkowo status połączenia jest sygnalizowany na belce statusowej. Grupa Sensory zawiera pięć elementów typu QProgressBar, które służą do
8
Rysunek 1: Interfejs graficzny aplikacji.
wizualizacji stanu czujników koloru. Elementy te mogą przyjmować wartości 0
lub 1. Następna grupa przedstawia prędkość silników. Uzyskiwane wartości z
mikrokontrolera są z zakresu 0- 255 i są one przeliczane na wartości procentowe,
które są wyświetlane. Grupa Wizualizacja zbiera ustawienia odnośnie wizualizowania stanu czujników. Pole Ćzas Interwałuókreśla czas w milisekundach co
jaki będzie odświeżany stan czujników. Liczba ustawiona w polu Ilość próbek
stanowi ilość uzyskanych odczytów z których będzie przeprowadzone określenie
ruchu robota. Dzięki przyciskom Start i Stop użytkownik decyduje o rysowaniu
trasy w okienku obok.
7
Diagram klas.
Diagram klas został przedstawiony na rysunku 2. Dla zachowania przejrzystości diagramu nie dodawano atrybutów klasy Ui MainWindow. Klasa ta zawiera
bardzo dużo elementów i jest generowana automatycznie przez Designera. Natomiast informacje dotyczące klasy QextSerialPort zawarta jest w dokumentacji
[1].
8
Schemat przepływu.
Schemat przepływu został przedstawiony na rysunku 3.
9
Testy oraz uzyskane wyniki.
Testy przeprowadzone zostały na zbudowanym i opisanym w punkcie 1 robocie.
Na podłodze została wyklejona czarną taśmą izolacyjną o szerokości 19mm. Taśma taka stosowana jest zwykle na zawodach line followerów. Na jasnej podłodze
czujniki zachowywały się tak jak na białej powierzchni także można było wykleić
dużo dłuższy tor. Droga posiada duży odcinek prostej, łagodny łuk oraz kilka
9
Rysunek 2: Diagram klas
Rysunek 3: Schemat blokowy
10
ostrzejszych i bliżej siebie położonych. Robot poprawnie przejeżdża tą trasę.
Aplikacja działa poprawnie pokazując stany czujników i prędkości. Łatwo można
zauważyć, jak szybko i często zmieniają się wartości sensorów. Ważnym parametrem jest ustalenie interwału timera. Za duży czas skutkowałem powolnym
odświeżaniem wartości. Bardzo mały czas rzędu 30 ms skutkowałem ciągłym
drganiem elementów wizualizacyjnych, przez co odczytanie czegokolwiek staje
się trudne. Z punktu dobrego odwzorowania przebywanej drogi konieczne jest
uzyskiwanie dużej ilości pomiarów w krótkim czasie. Im większa liczba próbek
tym lepsze następowało odwzorowanie. W związku z tym czas interwału powinniśmy ustawić na jak najmniejszy. Rozwiązaniem tego problemu było ustawienie
wyświetlania co 10 pomiaru. W ogólnym przypadku decyzję o czasie odświeżania
i ilości próbek zostawiono użytkownikowi.
10
Wnioski.
Zaimplementowana aplikacja realizuje postawione przed nią założenia. W poprawny sposób pozyskuje dane z mikrokontrolera oraz przetwarza je w należyty
sposób kontrolując przy tym różne błędy. Zaprojektowany interfejs graficzny w
przejrzysty sposób obrazuje stan czujników koloru oraz prędkości robota. Rysowanie trasy nie zostało zaimplementowane według początkowego pomysłu. Wynikłe podczas realizacji zadania problemy uniemożliwiły powstanie mini mapy
trasy poruszającego się robota. Rysowana droga nie pokrywała się z tą rzeczywistą, dlatego zrezygnowano z wyświetlania niepoprawnych rzeczy. Starano się
zaprojektować prosty i przejrzysty interfejs użytkownika. Wszystkie kontrolki
zostały umieszczone w centralnym oknie. Umożliwiają one głównie obsługę i
monitorowanie stanu połączenia oraz wpływ na parametry wizualizacji.
W związku z moim zainteresowaniem robotami i zawodami line followerów, w
przyszłości planuję rozwijanie mojej aplikacji. Chciałbym aby powstał system
kontroli i testowania poprawności algorytmów sterujących. Możliwe mogłoby
być również zmiana parametrów ustawień algorytmów, jak i również zatrzymywanie lub zmiana prędkości robota. Usprawniło by to na pewno pracę nad
sterowaniem tych robotów.
Literatura
[1] Dokumentacja platformy QextSerialPort.
[2] B. Kreczmer. Materiały do wykładu.
11

Podobne dokumenty