VII International Workshop for Candidates for a Doctor's Degree OWD 2005 22-25 October 2005 QSCRIPT JĘZYK PROGRAMOWANIA W ŚRODOWISKU WIELU ROBOTÓW QSCRIPT PROGRAMMING LANGUAGE IN THE MULTI ROBOT ENVIRONMENT Krzysztof Jaskot, Politechnika Śląska (16.12.2003, prof. Ryszard Gessing, Politechnika Śląska) Abstract The paper presents an experimental programming language QScript. In the paper we consider problem of using new programming language QScript to implementation finite state automaton. Using QScript programming language to control of a team of mobile robots is described. The paper presents also an application of neural network to reactive control of a mobile robot. Mobile robot is a machine that can operate in a human-made environment. By control in this case we will understand to be able to avoid collisions with obstacles during drive in unknown environment. Presented algorithm generates collision free path for the robot using neural network as a brain. Two algorithms based on the neural networks are described. The first described Braitenberg s algorithm fig. 3. The second uses BAM (Bi-directional Associative Memory) algorithm for modelling intelligent behaviour fig. 4. All of presented algorithms were written in Qscript language. Results of real application are also shown in table 1. Streszczenie W artykule przedstawiono język programowania w środowisku wieloagentowym bazujący na wykorzystaniu automatów skończonych jako efektywnego narzędzia do budowy skomplikowanych zachowań. Omówiono sposób jego wykorzystania do sterowania zespołem robotów mobilnych. Opisano warstwową strukturę systemu sterowania. Przedstawiono zbiór funkcji ściśle związanych ze sprzętem. Zaprezentowano wyniki działania języka QScript. Omówiono sposób wykorzystania automatów skończonych jako narzędzia zarządzania sztuczną inteligencją. 1. WSTĘP Programowanie robotów jako przedmiot badań istnieje od kilkunastu lat. W wielu pracach poruszana jest tematyka programowania robotów oraz specjalistycznych języków wspomagających ten proces [1,2,3]. W pracach tych najczęściej opisywane są języki programowania robotów przemysłowych. Obserwowany od kilku lat dynamiczny rozwój robotyki mobilnej zmusza badaczy do intensywnych poszukiwań nowych narzędzi programistycznych ułatwiających implementację algorytmów sterowania w środowisku wielu robotów a w szczególności robotów mobilnych. Dość nowym obszarem badawczym, w którym mamy do czynienia ze sterowaniem grupą robotów mobilnych jest piłka nożna robotów [4]. Jest to dobry przykład odwzorowania problemów świata rzeczywistego. Sterowanie grupą robotów mobilnych zwanych agentami w dynamicznie zmieniającym się otoczeniu wiąże się z wieloma zagadnieniami, do których należą: planowaniem działań, generowaniem bezkolizyjnych trajektorii ruchu robotów, konieczność działania na podstawie niepewnej i niekompletnej informacji. W systemach wieloagentowych duże znaczenie ma podział zadań i planowanie działań grupowych, występowanie zarówno współzawodnictwa - pomiędzy zespołami - jak i kooperacji między zawodnikami tego samego zespołu w celu realizacji określonego zadania i czy to będzie gra w piłkę czy inny problem wymaga to stworzenia odpowiednich algorytmów sterowania. 2. AUTOMAT STANÓW Ogólna definicja automatu stanów opisuje każdy model, który zawiera system sterowany zdarzeniami [5,6]. Zachowania systemu opisane są zbiorem stanów automatu, zbiorem zdarzeń wejściowych i funkcjami przejścia. Choć automat stanów może sterować w zasadzie dowolnym obiektem, najczęściej wykorzystuje się go w programowaniu sztucznej inteligencji. Za wykorzystaniem automatów skończonych jako narzędzia zarządzania zachowaniem robotów przemawia wiele cech. Automat stanów zmniejsza
złożoność zachowań, dzieląc je na prostsze fragmenty, którymi łatwiej manipulować. Program sterowania robotem można podzielić na kilka niezależnych podprogramów realizujących podstawowe zachowania (jazda, zmiana kierunku, obrót) a następnie uzyskać globalny system sterowania robotem poprzez składanie takich elementarnych zachowań. Jeżeli założymy, że aktywne będzie tylko jedno zachowanie to stany automatu mogą być bezpośrednio skojarzone z poszczególnymi zachowaniami robota. Automaty stanów na ogół wykorzystywane są do sterowania obiektami, gdyż umożliwiają selektywne wykonywanie kodu obiektu w zależności od jego aktualnego stanu. Automat może zapewniać synchronizację sztucznej inteligencji z zewnętrznymi zdarzeniami, na przykład pojawieniem się sygnału z sensorów. Automaty stanów są łatwiejsze w testowaniu i usuwaniu z nich błędów, zawsze wiemy, co wydarzy się w określonych warunkach, ponieważ przejścia stanów zostały zdefiniowane wcześniej i się nie zmieniają. Program sterujący działaniem agenta zrealizowany jako automat stanów nie wyklucza stosowania logiki rozmytej, sieci neuronowych i innych technik sztucznej inteligencji. Automat stanów zapewnia po prostu ogólny interfejs, który można rozszerzać według potrzeb. Lista funkcji, które powinien spełniać automat stanów to: Automat stanów może mieć dowolną liczbę stanów, Stany można łatwo określić i ustawić, Gdy wchodzisz do stanu, masz możliwość wykonywania dowolnego kodu inicjalizującego, Gdy wychodzisz ze stanu, masz możliwość wykonania dowolnego kodu czyszczącego, Może wysłać komunikat do dowolnego agenta nawet samego siebie. 3. JĘZYK QSCRIPT Język QScript został zaprojektowany w celu łatwej i szybkiej implementacji automatów skończonych obsługujących system wieloagentowy. Głównym założeniem przyjętym w fazie projektowania języka była prostota składni, która została osiągnięta przez sięgnięcie do analogi syntaktycznej rodem z C [7]. Innym ważnym założeniem było wyposażenie systemu sterowania we własny kompilator języka QScript, co wyeliminowało konieczność posiadania zewnętrznego kompilatora. Razem z kompilatorem /interpreterem języka została dostarczona pokaźna biblioteka zorganizowanych hierarchicznie funkcji, tak matematycznych, jak również specjalizowanych w wykonywaniu działań specyficznych dla systemu wieloagentowego. Programy napisane w języku QScript oferują dobrą wydajność dzięki kompilacji do kodu wykonywalnego procesora Dzięki mechanizmowi callback programy mogą symulować funkcjonalność, której brakuje w danej implementacji kodu agenta, tzn. istnieje prosta metoda testowania nowych funkcji agenta przed zaszyciem ich w krzemie, w sposób praktycznie przezroczysty dla aplikacji-automatu skończonego. Implementacja języka QScript zawiera pokaźną bibliotekę funkcji wbudowanych. Poniżej przedstawione jest kilka wybranych funkcji bezpośrednio związanych ze sterowaniem robotem: Robot.GetAngle() pobiera orientacje robota, Robot.GetPositionX() pobiera pozycję x robota, Robot.GetPositionY() pobiera pozycję y robota, Robot.GetSenorReading(kąt, zakres, 1) odczyt danych z wirtualnych sensorów, Robot.Rotate(kąt) obraca robota o zadany kąt. Udostępnienie bogatego zestawu funkcji do obsługi specyficznych elementów systemu pozwala na dostarczenie interfejsu, w którym nie jest wymagana znajomość programowania na poziomie sprzętowym. Na rysunku 1 przedstawiono możliwość wykorzystania mechanizmu "callback" oraz funkcji wbudowanych do emulacji czujników zbliżeniowych. Dzięki mechanizmowi "callback" posiadamy możliwość przetestowania funkcji lub właściwości sprzętowych robota jeszcze przed ich fizyczną realizacją np. rozmieszczenie czujników na korpusie robota. Ma to duże znaczenie w czasie prac projektowych związanych z budową robota gdyż pozwala na wprowadzanie zmian w konfiguracji i wybraniu rozwiązania optymalnego z punktu widzenia działania np. omijanie przeszkód.
jego zmiany. Aktualizacja automatu stanów w realizowana jest 30 razy na sekundę. Poniżej przedstawiony jest przykład definiowania automatu stanu. start_state stmain void OnEnter() // wejście do stanu void OnUpdate() void OnExit() // wyjście ze stanu 5. WYNIKI Rys.1. Emulacja czujników zbliżeniowych. Fig.1. Emulation of proximity sensors. 4. DEFINIOWANIE AUTOMATU Każdy program w języku QScript jest w istocie podaną explicite definicją automatu skończonego. Automat taki złożony jest z listy definiującej poszczególne stany układu. Na definicję każdego stanu składają się trzy procedury, wywoływane przy wchodzeniu do danego stanu, przy jego aktualizacji, oraz przy wychodzeniu z niego. Każda procedura może zawierać instrukcje nakazujące zmienić stan na inny. Ponadto automat może zawierać definicje procedur niezwiązanych z konkretnym stanem a dostępnych z dowolnego miejsca kodu. Pozwala to na strukturalizację programu i czyni kod bardziej przejrzystym, ponadto likwiduje konieczność duplikowania podobnych fragmentów kodu występujących w różnych stanach. W definicji automatu mogą znaleźć się również definicje zmiennych globalnych. W automacie skończonym można w każdej chwili wskazać jeden z dostępnych stanów jako stan bieżący, tzn. stan, którego kod jest wykonywany podczas kolejnych aktualizacji automatu, do chwili Prezentowany język programowania QScript został wykorzystany do sterowania zespołem trzech robotów. Podstawą konstrukcji testowych robotów jest aluminiowy korpus, w którym osadzona jest nieruchoma oś oraz 2 wysokoobrotowe silniki napędowe prądu stałego o mocy 4.55W każdy, dwa przetworniki obrotowo-impulsowe (enkodery) 512 imp./obr., akumulatorowe źródło zasilania NiCd o pojemności 450mAh i napięciu 7.2V. Napęd na koła przenoszony jest za pomocą przekładni zębatych. Robot rozwija prędkość ok. 150cm/s. Oprócz części mechanicznej robot wyposażony jest w sterownik pokładowy. Zadaniem sterownika jest: sterowanie silnikami napędowymi, pomiar prędkości obrotowej kół, przetwarzanie danych pomiarowych oraz obsługa komunikacji ze sterownikiem nadrzędnym. Rys.2. Roboty wykorzystane w teście. Fig.2.Test robots. Jako narzędzi sprawdzających możliwości i przydatność języka QScript do sterowania
robotami mobilnymi wykorzystano algorytmy reaktywne [8]. 5.1. ALGORYTM BRAITENBERG A Istotą tego rozwiązania jest bezpośrednie połączenie modułów percepcji i wykonywania ruchów. Klasycznym przykładem modelu reaktywnego jest algorytm Braitenberg a [9]. Idea tego algorytmu opiera się na bezpośrednim połączeniu czujników z elementami wykonawczymi. Każde połączenie posiada wagę. W zależności od rodzaju zastosowanych czujników i wartości wag robot może wykonywać różne zadania: podążać do źródła światła lub go unikać, omijać przeszkody, itp. Sygnały sterujące dla silnika lewego i prawego są obliczane w następujący sposób: v v l p 8 l xiwi i1 8 xiwi i1 v p v (1) (2) Gdzie: x i sygnał z i-tego czujnika, w i l,w i p odpowiednio wagi dla lewego i prawego silnika, v zadana prędkość poruszania się. Można zauważyć, że zależności (1) i (2) są formą łącznego pobudzenia neuronu z tego faktu wynika że jest to sieć jednowarstwowa posiadająca dwa neurony o liniowych funkcjach aktywacji. Niewątpliwą zaletą tego algorytmu jest jego prostota, lecz wadą to, że nie można przewidzieć jak w danej sytuacji zachowa się robot. Poniżej przedstawiony jest fragment programu napisany w języku QScript realizujący algorytm Braitenberg'a gdzie s0...s5 - sygnały z czujników, vl,vr - wyjście sieci zgodne z (1,2). s0=robot1.getsensorreading(5*math.pi()/3, 0.2,1); : s5=robot1.getsensorreading(5*math.pi()/4, 0.2,1); vr=s0*(-5)+s1*(- 8)+s2*(8)+s3*(6)+s4*(4)+s5*(4)+15; vl=s0*(4)+s1*(4)+s2*(6)+s3*(-18)+s4*(- 15)+s5*(-5)+15; Robot1.SetVelocity(vl,vr); Na rysunku 3 przedstawione są przykładowe trajektorie dla trzech robotów, które poruszały się wykorzystując właściwości algorytmu Braitenberg'a. Rys.3. Przykładowe trajektorie. Fig.3. Example of trajectory. 5.2. DWUKIERUNKOWA PAMIĘĆ ASOCJACYJNA Inną metodą testowaną z powodzeniem jest dwukierunkowa pamięć asocjacyjna. Pamięć asocjacyjna (skojarzeniowa) jest jednym z podstawowych atrybutów ludzkiego mózgu. Pamięć taka ma dwie istotne cechy, odróżniające ją w sposób zasadniczy od pamięci systemów technicznych np. komputerowych. Po pierwsze, jak wynika z jej nazwy, informacje zarejestrowane w pamięci asocjacyjnej mogą być dostępne poprzez podanie na wejściu systemu informacji skojarzonej, selekcjonującej jedną z zapamiętanych wiadomości na drodze asocjacji, a więc na drodze zdecydowanie odmiennej od dostępu adresowego, charakterystycznego dla systemów obliczeniowych. Po drugie ślad pamięciowy zwany czasami engramem nie ma w pamięci asocjacyjnej ścisłej lokalizacji, gdyż każda zarejestrowana informacja zlokalizowana jest w istocie w całej pamięci, na zasadzie kolektywnego działania wszystkich jej elementów [10]. Proces uczenia wag (kodowanie wag) nie odbywa się poprzez uczenie w sensie zwykłym, ale na drodze obliczeniowej, wykorzystując dane wektory uczące A i B stowarzyszone ze sobą. Macierz wag W jest obliczana jako suma iloczynów wektorowych A i B: N W i1 A i B i T (3) Macierz W określa parametry sieci i stanowi jej pamięć. Każdy wektor otrzymany jako odpowiedź podlega normalizacji tzn. elementy większe od zera przyjmują wartość +1, a mniejsze 1. Odpowiedź układu otrzymujemy z:
R W T Ai (4) Dokładne informacje na temat wykorzystania pamięci asocjacyjnej można znaleźć w pracy [8]. Poniżej przedstawiony jest fragment programu realizujący algorytm dwukierunkowej pamięci asocjacyjnej. Gdzie s0...s3 sygnały z czujników, SL, SR uśrednione sygnały z czujników. W[i] macierz wag (3), R[i] odpowiedź sieci czyli sterowanie (4). s0=robot1.getsensorreading(5*math.pi()/3, 0.2, 1); : s3=robot1.getsensorreading(5*math.pi()/4, 0.2, 1); SL=(s0+s1)/1023; SR=(s2+s3)/1023; R[0]=W[0]*SL+W[1]*SR; R[1]=W[2]*SL+W[3]*SR; Robot1.SetVelocity(R[0],R[1]); Wynik sterowania grupą trzech robotów z wykorzystaniem algorytmu opartego na pamięci asocjacyjnej przedstawiony jest na rysunku 4. Rys.4. Przykładowe trajektorie. Fig.4. Example of trajectory. Prezentowane powyżej metody sterowania robotem mobilnym są metodami, które posiadają poważną wadę. Nie jesteśmy w stanie przewidzieć jak się zachowa nasz robot w danej sytuacji. Metody te nadają się do zastosowania wtedy, gdy posiadamy dodatkowy mechanizm koordynujący zachowanie robota. W naszym przypadku takim mechanizmem jest system sterowania robotów wyposażony w system wizyjny, którego zadaniem jest kontrola zachowania poszczególnych robotów. Reaktywne metody sterowania robotami doskonale sprawdzają się w sytuacjach awaryjnych, w których konieczna jest szybka zmiana trajektorii ze względu na pojawienie się przeszkody. Metody te nie wymagają dużego nakładu obliczeniowego. 6.WNIOSKI Prezentowany język QScript został porównany z implementacją automatów skończonych zrealizowanych w języku Visual C++ i Builder C++. W celach testowych porównano czasy realizacji automatu składającego się z 5,10,15,20 i 25 stanów. Testowy automat stanów, realizował tylko proces przełączania się między stanami. Nie testowano specyficznych właściwości języka QScript do sterowania robotami ze względu na brak ich implementacji w języku C++. Pomiar czasu rozpoczynał się przy wejściu do pierwszego stanu a kończył przy wyjściu z ostatniego. Wyniki zostały przedstawione w tabeli 1. Tab.1. Porównanie implementacji algorytmów. Compare of algorithms implementation. L. stanów QScript VC++ Builder C 5 1.6ms 3.5ms 4.0ms 10 3.3ms 7.2ms 8.1ms 15 5.0ms 11.1ms 15.0ms 20 6.5ms 13.3ms 17.9ms 25 8.3ms 17.0ms 21.0ms Wydajność implementacji algorytmu sterowania zależy od rozmiaru automatu. W przypadku kompilatora Visual C++ i Builder C++ konstrukcja switch użyta do budowy automatu rozwijana jest do instrukcji if-then-else, co jest bardzo trudne w optymalizacji. Dla automatu posiadającego n stanów program potrzebował wykonać około 2n porównań if-thenelse by znaleźć właściwą funkcję. Odpowiada to około dwukrotnemu zwiększeniu czasu potrzebnego do realizacji zadania. Analiza powyższych wyników pozwala nam stwierdzić, że specjalizowany język programowania przeznaczony do implementacji algorytmów sterowania z wykorzystaniem automatów skończonych jest bardziej efektywny w porównaniu z implementacją wykonaną w C++. Jednak trzeba zdawać sobie sprawę z tego, że czas wykonywania kodu generowanego przez narzędzia typu Lex i Yacc jest dłuższy. Wynika to z faktu, że analizator kreowany przez Lex'a i Yacc wprowadza tylko podstawową optymalizację. Dopiero ręczne poprawienie pewnych procedur z punktu widzenia szybkości działania umożliwia otrzymanie wyników, które prezentowane są w tabeli 1. Procedury, które powodowały opóźnienia zostały zoptymalizowane i napisane w całości w C/Assembler. Jeżeli weźmiemy jako całkowity czas obliczeń potrzebnych do realizacji całego
procesu sterowania czas trwania jednej klatki, który wynosi 33ms to musimy sobie zdawać sprawę z pewnych ograniczeń czasowych. W tym czasie musi zostać zrealizowane przetwarzanie informacji wizyjnej, wykonanie programu napisanego w języku QScript, wysłanie sterowania do robotów lub obliczenia potrzebne do symulacji. Dlatego tak ważnym elementem jest tutaj czas realizacji samego algorytmu sterującego. Niniejsza praca finansowana była z funduszu KBN 3T11A 02928. e-mail: krzysztof.jaskot@polsl.pl Adres służbowy Autora: mgr inż. Krzysztof Jaskot Instytut Automatyki, Politechnika Śląska ul. Akademicka 16, 44-101 Gliwice tel.: (32) 2372750, fax.: (32) 2371165 LITERATURA 1. Craig J. J.: Wprowadzenie do robotyki. Mechanika i sterowanie, Wydawnictwa Naukowo-Techniczne, Warszawa 1995. 2. Morecki A., Knapczyk J.: Podstawy robotyki, Wydawnictwa Naukowo- Techniczne, Warszawa 1994. 3. Zieliński C. : Robot programming methods, Elektronika z. 107, Politechnika Warszawska, 1995. 4. Kozłowski K. et al.: Mobile Robot Soccer, MMAR, Międzyzdroje, 2000. 5. Cichosz P.: Systemy uczące się. Wydawnictwa Naukowo-Techniczne, Warszawa 2000. 6. DeLoura M.: Perełki programowania gier T.1 i T.2. Wydawnictwo Helion, Gliwice 2002. 7. Kernighan B.W., Ritchie D. M.: Język ANSI C, Wydawnictwa Naukowo-Techniczne, Warszawa 2000. 8. Jaskot K.: Zastosowanie sieci neuronowych do sterowania reaktywnego robotem mobilnym, IV Ogólnopolskie Warsztaty Doktoranckie, Istebna-Zaolzie 2002. 9. Braitenberg V. : Vehicles: Experiments in synthetic psychology, MIT Press, Cambridge 1984. 10. Tadeusiewicz R. : Sieci neuronowe, Akademicka Oficyna Wydawnicza, Warszawa 1993.