POLITECHNIKA ŚLĄSKA WYDZIAŁ INśYNIERII MATERIAŁOWEJ I METALURGII Specjalność: Informatyka UŜytkowa Kierunek: Edukacja Techniczno - Informatyczna Rodzaj studiów: Jednolite magisterskie Praca dyplomowa magisterska Arkadiusz MATALEWSKI Sterowanie urządzeniami mechanicznymi za pomocą systemu detekcji myśli. Recenzent dr hab. Tadeusz Wieczorek prof. nzw. w Pol. Śl. Promotor dr inŝ. Mirosław Kordos Katowice, wrzesień 2009
Spis treści I. Część teoretyczna...3 1. Wstęp...3 2. Cel i zakres pracy...3 3. Microsoft Visual Studio 2008...4 3.1. Microsoft Visual Studio (MVS)...4 2.2. Architektura MVS...5 3.3. Narzędzia...6 4. Emotiv SDK... 11 4.1. EmoKey... 12 4.2. EmoComposer... 16 4.3. Emotiv Control Panel (ECP)... 18 4.4. edk.dll... 21 5. Neurohełm EmotivEpoc... 23 II. Część praktyczna... 25 1. Kod źródłowy... 25 2. Schemat sterowania samochodem... 31 3. Podsumowanie... 35 III. Literatura... 36 2
I. Część teoretyczna 1. Wstęp Od kiedy człowiek stworzył jakiekolwiek urządzenie mechaniczne, chciał nim sterować w jak najprostszy, najefektywniejszy oraz najszybszy sposób. Sterowanie urządzeniami przyjmowało róŝne formy: piloty zdalnego sterowania (do telewizora, sterowania modelami samochodów itp.), joysticki (do sterowania grami komputerowymi), róŝnego rodzaju układy sterowania (układ kierowniczy w samochodzie). Wszystkie te rozwiązania sprawdziły się i działają do tej pory, lecz posiadają pierwotny defekt. Nie są najszybsze, ani teŝ najprostsze poniewaŝ sterowanie odbywa się manualnie. Rozwiązaniem defektu zajęła się nowa firma z San Francisco Emotiv Systems. Firma ta stworzyła prosty w obsłudze neurohełm, który wprowadza nas w nową erę sterowania urządzeniami za pomocą myśli, stanu emocjonalnego czy wyrazu twarzy. Czy moŝe być prostszy sposób sterowania jak tylko myśl, uśmiech czy mrugnięcie okiem. Wyobraźmy sobie, Ŝe wchodzimy do domu po cięŝkim dniu, zakładamy neurohełm i w momencie, gdy zostaje odczytany nasz zły nastrój z głośników zestawu audio, słyszymy ulubioną piosenkę. Wprawdzie mamy jeszcze daleką drogę do przebycia, aby móc w pełni sterować urządzeniami za pomocą myśli, ale juŝ stawiamy pierwsze kroki w tej dziedzinie, czego przykładem jest niniejsza praca. 2. Cel i zakres pracy Celem pracy dyplomowej jest zaprezentowanie moŝliwości sterowania obiektami ruchomymi za pomocą myśli. Myśli czytane są za pomocą neurohełmu produkcji firmy Emotiv Systems. Firma zaprojektowała i wykonała go jako urządzenie czytające fale mózgowe EEG. Myśli zostają zinterpretowane i wysłane do jednostki centralnej w postaci kodu. Jako urządzenie sterowane wykorzystany został samochód zabawka firmy Nikko ze zmodyfikowanym pilotem sterowania. Modyfikacji pilota dokonano w celu podłączenia go do jednostki centralnej za pomocą portu szeregowego. Wszystkie polecenia wysyłane z hełmu przechwytywane są przez program, a następnie wysyłane przez port szeregowy do pilota, który kontroluje samochód drogą radiową.. System sterowania pojazdem przy pomocy sygnałów z neurohełmu został stworzony w środowisku Microsoft Visual Studio. Zakres pracy obejmował: Zapoznanie się ze środowiskiem Microsoft Visual Studio. 3
Zapoznanie się ze środowiskiem Emotiv Software Development Kit. Zapoznanie się z moŝliwościami neurohełmu Emotiv Epoc. Napisanie programu umoŝliwiającego sterowanie samochodem za pomocą sygnałów wysyłanych z neurohełmu. 3. Microsoft Visual Studio 2008 3.1. Microsoft Visual Studio (MVS) Microsoft Visual Studio (MVS) jest głównym zintegrowanym środowiskiem programistycznym (IDE) firmy Microsoft. Środowisko to moŝe być wykorzystywane do tworzenia aplikacji konsolowych lub graficznego interfejsu uŝytkownika (GUI), dla wszystkich platform wspieranych przez Microsoft Windows, Windows Mobile,.NET Framework,.NET Compact Framework oraz Microsoft Silverlight. Na Visual Studio składa się wiele narzędzi między innymi zintegrowany debugger, konstruktor formularzy dla aplikacji GUI, konstruktor klas oraz konstruktor baz danych. Środowisko to pozwala równieŝ na dodawanie wielu innych modułów, które mogą zwiększyć funkcjonalność na praktycznie kaŝdym poziomie np. system kontroli kodu (Visual SourceSafe). Wymagania dla MVS 2008: 32 bit SO: Windows XP Professional Service Pack 2, Windows Server 2003, Windows Vista, 64 bit SO: Microsoft Windows Server 2003 SP1, Standard x64 Edition Microsoft Windows Server 2003 SP1, Enterprise x64 Edition Microsoft Windows Server 2003 SP1, Datacenter x64 Edition Microsoft Windows Server 2003 R2, Standard x64 Edition Microsoft Windows Server 2003 R2, Enterprise x64 Edition Microsoft Windows Server 2003 R2, Datacenter x64 Edition Microsoft Windows XP Professional x64 Edition Windows Vista 4
Wymagania sprzętowe: Minimalne: 2.0 GHz CPU, 512 MB RAM, 8 GB miejsca na dysku Zalecane: 2.6 GHz CPU, 1 GB RAM, 20 GB miejsca na dysku [1] 2.2. Architektura MVS MVS nie wspiera języków programowania ani narzędzi, natomiast pozwala na dodawanie ich. Wszystkie języki programowania, edytory, konstruktory, rodzaje projektów oraz inne narzędzia są implementowane jako pakiety VSPackages. Visual Studio uŝywa interfejsu COM do komunikacji z VSPackages. MVS posiada trzy najwaŝniejsze pakiety: SVsSolution, pakiet odpowiedzialny jest za numerowanie projektów, tworzenie nowych projektów oraz monitorowanie zmian w projektach. SVsUIShell, pakiet dostarcza okienka oraz interfejs uŝytkownika, zakładki, menu z narzędziami itp. SVsShell, pakiet jest odpowiedzialny za rejestrowanie wszystkich innych pakietów oraz zarządzanie nimi. [2] Wsparcie dla języków programowania jest dodawane poprzez odpowiednie pakiety VSPackages zwane usługami języków. Pakiety te wspierają róŝną funkcjonalność np. kolorowe podkreślanie błędów, uzupełnianie komend, wyskakujące okienka, itp. Część języków programowania juŝ ma wbudowane pakiety w instalatora MVS są to między innymi: C C++ VB.NET C# JeŜeli koniecznym jest współpracowanie z innymi językami takimi jak: Chrome, F#, Phyton, Ruby, naleŝy dopiąć dodatkowe pakiety zawierające informacje o tych językach.[3] Visual Studio nie zawiera Ŝadnego systemu kontroli kodu, ale ma wbudowany system MSSCCI (Microsoft Source Code Control Interface), który definiuje zestaw funkcji jakie zostały zaczerpnięte z innych juŝ istniejących systemów kontroli kodu. Na początku system ten został uŝyty do integracji Visual Studio 6.0 z systemem Visual SourceSafe. Z czasem jednak rozwinięto go i w wersji 1.1 został uŝyty w MVS 2002. Natomiast w MVS 2003 wykorzystano wersję 1.2 MSSCCI. MVS 2008 wykorzystuje juŝ kolejną wersję 1.3 MSSCCI, 5
która wspiera zmienianie nazw, usuwanie oraz asynchroniczne otwieranie.[4] MVS pozwala równieŝ na otwieranie wielu wersji środowiska jednocześnie, kaŝdą z innymi pakietami. Wszystkie wersje uŝywają innego gniazda rejestru w celu zapisania ustawień wykorzystywanych pakietów itp. KaŜda z tych wersji posiada równieŝ inny AppID (Application ID- identyfikator aplikacji). [3] 3.3. Narzędzia Visual Studio jak kaŝde zintegrowane środowisko programistyczne, zawiera edytor kodu. Edytor wspiera podświetlanie błędów oraz uzupełnianie kodu, nie tylko dla zmiennych, metod czy funkcji lecz równieŝ dla zapytań oraz pętli. System uzupełniania kodu nosi nazwę IntelliSense i wspiera wszystkie zaimplementowane języki programowania, jak i XML oraz JavaScript dla tworzenia aplikacji sieciowych oraz stron internetowych. Uzupełnianie kodu pojawia się jako rozwijane menu obok właśnie pisanego kodu (rys. 1). W MVS 2008 wprowadzono moŝliwość chwilowego wywołania półprzeźroczystości menu w celu obserwacji pisanego kodu.[5] Edytor kodu w celu szybkiej nawigacji po kodzie, pozwala na umieszczanie zakładek w kodzie oraz zwijanie konkretnych części kodu (rys. 2).[3] Microsoft w Visual Studio wprowadził tzw. kompilacje w tle polegające na tym, iŝ w momencie pisania kodu jest on sprawdzany pod kątem działalności. Błędy są automatycznie podkreślane czerwoną falującą linią, natomiast ostrzeŝenia zieloną falująca linią (rys. 3). Taka kompilacja nie daje nam kodu z moŝliwością uruchomienia. Kod nadal musi zostać skompilowany odpowiednim kompilatorem.[6] Rys. 1. Rozwijane menu systemu IntelliSense odpowiedzialnego za uzupełnianie kodu. 6
Rys. 2. Zwijanie kodu po lewej stronie przed zwinięciem po prawej po. Rys. 3. Kompilacja w tle ujawniająca ostrzeŝenie (pierwsza linia kodu zielone podkreślenie), oraz błąd (druga linia kodu czerwone podkreślenie). Jak wspomniano w rozdziale 3.1 Microsoft Visual Studio (MVS) MVS zawiera zintegrowany debugger, który działa zarówno na poziomie maszynowym jak i kodu. Debugger moŝe być uŝyty dla kaŝdego języka programowania wspieranego przez Visual Studio. MoŜemy go równieŝ tak skonfigurować, aby uruchamiał się dla kaŝdego programu, przy wykonywaniu, którego wystąpił błąd, nawet jeŝeli nie był uruchamiany ze środowiska Visual Studio. Dzięki temu narzędziu moŝemy teŝ przeprowadzić zrzut pamięci i jednocześnie wgrywać w celu późniejszego sprawdzenia poprawności kodu.[3,7] Istnieje takŝe moŝliwość ustawianie tzw. punktów przerwania (rys. 4). Są to miejsca w kodzie, w których program zatrzymuje się. Dzięki temu moŝemy sprawdzić, co dzieje się krok po kroku w programie. Podczas takiego zatrzymania mamy równieŝ moŝliwość sprawdzenia na monitorze w dolnej części okna MVS wartości dla kaŝdej zmiennej (rys. 5). Wartości te moŝna równieŝ w tym momencie sprawdzić poprzez najechanie wskaźnikiem myszy na daną zmienną. Debugger wspiera takŝe opcje zmień i kontynuuj. Pozwala to na zmianę kodu podczas jego debuggowania (rys. 6). [8,9,10] Rys. 4. Ustawienie punktów przerwania dla kodu w MVS. Rys. 5. Edycja zmiennych w trakcie działania debuggera. 7
Rys. 6. Monitor wartości zmiennych w momencie wejścia na punkt przerwania. MVS w celu ułatwienia projektowania nowych aplikacji zawiera narzędzia zwane konstruktorami. Większość z nich działa na zasadzie przeciągnij i upuść. Podstawowym konstruktorem jest konstruktor WinForms (rys. 7). Tworzenie okna aplikacji odbywa się poprzez wybieranie odpowiedniej kontrolki ze skrzynki narzędzi po lewej stronie ekranu i przeciągnięcie jej na okienko aplikacji (rys. 8). KaŜdą taka kontrolkę moŝemy następnie dowolnie skonfigurować (nazwa kontrolki, wielkość, kolor itp.) dzięki menu, które znajduje się u dołu prawego rogu konstruktora. Kolejnym konstruktorem jest konstruktor sieci. Pozwala on na tworzenie stron internetowych. Działa na takiej same zasadzie jak konstruktor WinForms, czyli przeciągnij i upuść kontrolki ze skrzynki narzędzi. Pozwala teŝ na tworzenie aplikacji ASP.NET oraz wspiera kod HTML oraz JavaScript. Kolejnym waŝnym konstruktorem jest konstruktor danych. UmoŜliwia on na edycję bazy danych w formie graficznej (tabele, klucze, schematy itp.). Ponadto mamy moŝliwość tworzenia zapytań.[3] Ostatnim omówionym tutaj aspektem MVS jest rozszerzalność tego środowiska. MVS pozwala programistom na poszerzanie swoich moŝliwości dzięki dopinanym rozszerzeniom. Rozszerzenia te występują w trzech odmianach: makra są to programowalne powtarzalne czynności, które programista moŝe uruchomić za kaŝdym razem, gdy tego potrzebuje. Są one najniŝszym poziomem rozszerzalności, gdyŝ nie dodają Ŝadnych nowych komend, czy teŝ okien narzędzi. Makra są pisane w języku Visual Basic i nie są kompilowane. 8
dopięcia (addons) dzięki dostępowi do modelu obiektów MVS mogą korzystać z juŝ istniejących narzędzi środowiska. Dzięki temu pozwalają na zwiększanie funkcjonalności juŝ istniejących narzędzi oraz na dodawanie nowych. pakiety dają moŝliwość tworzenia nowych konstruktorów, narzędzi a nawet implementacji nowych języków programowania. Tworzone są one za pomocą Visual Studio SDK (Software Development Kit).[11] Opcja ta jest niedostępna tylko w bezpłatnej wersji Visual Studio Express Editon. Została wprowadzona do MVS od wersji 2005. W wersji MVS 2008 wprowadzono Visual Studio Shell, który umoŝliwia programistom na tworzenie własnych skonfigurowanych wersji MVS. Visual Studio Shell zawiera nie tylko podstawowe pakiety niezbędne do działania jakiegokolwiek zintegrowanego środowiska programistycznego, ale dopuszcza na dodawanie dowolnych pakietów podczas instalacji. Tak stworzonemu środowisku nadawany jest osobny identyfikator aplikacji (AppId) oraz tworzony jest dodatkowy plik uruchamiający. Pozwala to na dostosowywanie środowiska do potrzeby kaŝdego języka programistycznego lub wybranego scenariusza pracy.[3] 9
Rys. 7. Wygląd interfejsu do graficznego projektowania MVS 2008. 10
Rys. 8. Skrzynka narzędzi MVS 2008. 4. Emotiv SDK Cały ten rozdział został oparty o źródło [12] oraz [13]. Emotiv Software Development Kit jest to zestaw narzędzi dzięki, którym moŝna tworzyć oraz testować aplikacje wykorzystujące neurohełm. Na zestaw składają się 3 narzędzia: EmoKey - narzędzie umoŝliwiające na przypisanie odpowiednich kombinacji klawiszy klawiatury po odczytaniu z hełmu konkretnego zachowania uŝytkownika np. rozmawiając z kimś poprzez komunikator moŝemy skonfigurować EmoKey tak, aby w momencie wykrycia na twarzy uŝytkownika uśmiechu automatycznie zostanie wysłana komenda hahaha na komunikator. EmoComposer - narzędzie symulujące pracę hełmu. SłuŜy głównie do testowania współpracy pomiędzy hełmem oraz aplikacją. Pozwala na ręczne wysłanie poleceń do aplikacji oraz uruchamianie wcześniej skryptów. Emotiv Control Panel (ECP) narzędzie pozwalające na demonstracje, dopasowanie, uczenie oraz testowanie czystości połączenia z hełmem. 11
4.1. EmoKey Rys. 9. Wykorzystanie hełmu w komunikacji z aplikacją poprzez EmoKey. Na rys. nr 9 przedstawiono schemat działania neurohełmu przy współpracy z narzędziem EmoKey. Neurohełm odbierając sygnał z mózgu przesyła go do bezprzewodowego odbiornika, z którym następnie komunikuje się EmoKey sprawdzając swoje reguły. Po czym wysyła odpowiednie polecenia dla danej aplikacji. EmoKey zaraz po uruchomieniu próbuje połączyć się z ECP. JeŜeli komunikacja nie powiedzie się uŝytkownik zostaje o tym zawiadomiony poprzez ostrzeŝenie nad ikoną systemową EmoKey. Celem łączenia się EmoKey z ECP zamiast bezpośrednio z neurohełmem, jest danie moŝliwości uŝytkownikowi na wybór własnego profilu. Rys. 10. Wybór narzędzi z którymi moŝe się połączyć EmoKey. 12
Więcej o profilach uŝytkowników jest w rozdziale 4.3. Emotiv Control Panel. EmoKey moŝna równieŝ połączyć z EmoComposer dzięki, któremu moŝemy w prosty sposób przetestować czy powiodło się mapowanie stanów. Konfigurator reguł dla EmoKey jest prostym interfejsem typu wybierz i kliknij. W celu dodania nowej reguły klikamy na przycisk Add Rule, a w celu usunięcia zaznaczamy ją, a następnie klikamy przycisk Delete Rule. W tabeli numer 1 przedstawiono poszczególne pola konfiguratora reguł oraz załoŝeń wraz z ich opisem. Nazwa pola Opis Enabled Pole pozwalające na wyłączenie/włączenie konkretnej reguły lub załoŝenia. Player Identyfikuje z którego neurohełmu ma przyjść impuls uruchamiający regułę. Name Nazwa reguły. Key(s) Kombinacja klawiszy klawiatury która zostanie uŝyta po spełnieniu załoŝeń reguły. Behavior Pole odpowiedzialne za to czy dana reguła zostanie uruchomiona tylko raz po spełnieniu jej załoŝenia, czy teŝ będzie wysyłana za kaŝdym razem gdy nastąpi uaktualnienie stanu neurohełmu. Action Nazwa stanu jaki ma zostać spełniony w celu uruchomienia reguły. Trigger ZałoŜenie do spełnienia np. większe, mniejsze, pojawiło się itp. Value Wartość jaką musi przekroczyć lub spełnić załoŝenie w celu uruchomienia reguły. Tabela. 1. Pola konfiguratora reguł EmoKey. 13
Rys. 11. Konfigurator reguł EmoKey. Jak widać na rys. nr 11 moŝna dowolnie zdefiniować co będzie działo się, gdy zostanie spełniony odpowiedni warunek. MoŜna równieŝ wysłać jako komendy kombinacje skrótów klawiszowych z wykorzystaniem klawiszy CTRL, ALT, SHIFT, WINDOWS oraz dowolny jaki dodamy. Konfigurator daje nam równieŝ moŝliwość zdefiniowania jak długo dana kombinacja przycisków ma być przytrzymana lub w jakich odstępach czasu będą wypisywane następne znaki wyraŝenia. Czas podajemy w milisekundach. Dla kaŝdej reguły moŝemy ustalić kilka załoŝeń, które muszą być spełnione w celu jej uruchomienia. Przedstawiono to na rys. nr 12, gdzie załoŝeniem jest uśmiech przynajmniej na poziomie 0,4 w skali od 0 do 1. 14
Rys. 12. Definiowanie załoŝeń dla reguł w EmoKey. Po stworzeniu reguł dla jakiejkolwiek aplikacji moŝemy je zapisać w pliku.xml w celu późniejszego wykorzystania, gdy nastąpi konieczność uŝycia tej samej aplikacji. MoŜemy w ten sposób zdefiniować inne reguły dla komunikatora Gadu-Gadu i inne reguły dla komunikatora Tlen, i w zaleŝności od tego, którego uŝywamy moŝemy wgrywać osobny zestaw reguł. 15
4.2. EmoComposer Rys. 13. Schemat współpracy EmoComposer z aplikacjami. EmoComposer pozwala uŝytkownikowi na wysłanie zdefiniowanych stanów do Emotiv Contro Panel, EmoKey lub aplikacji które wykorzystują bibliotekę edk.dll. EmoComposer wykorzystuje dwie metody generowania stanów. Jednym jest interaktywne menu dzięki, któremu moŝemy definiować i wysyłać stany, drugi to specjalnie przygotowane skrypty. NiŜej opisane są moŝliwości uŝytkownika związane z wysyłaniem stanów z interaktywnego menu: Player definiuje numer uŝytkownika, którego stan będziemy definiować i wysyłać do aplikacji. Wireless ustawia symulacje bezprzewodowej komunikacji neurohełmu ze stacją roboczą. EmoState pozwala na ustawienie wszystkich moŝliwych stanów i moc z jaką będą działać. MoŜna zarówno wysyłać sygnał jako stan emocjonalny (podniecenie, znuŝenie), fale mózgowe odpowiedzialne za zmienianie pozycji przedmiotów 16
(popchnij, pociągnij, obróć w lewo) oraz odczytać wyraz twarzy (uśmiech, mrugnięcie, spojrzeć w prawo). Auto Repeat pozwala na zdefiniowanie EmoComposer, tak aby wysyłał stany w czasie rzeczywistym, regularnie powtarzając poprzedni stan. Send wysyła pojedynczy stan lub z zaznaczoną opcją auto repeat - rozpoczęcie serii stanów. Ustawienia dla skryptów: Player - definiuje numer uŝytkownika, którego stan będzie definiowany i wysyłany do aplikacji. File wgrywa pliki skryptów. Start uruchamia plik skryptu, który wysyła w odpowiednim czasie stan. Rys. 14. Interaktywne menu oraz menu skryptów EmoComposer. 17
4.3. Emotiv Control Panel (ECP) Rys. 15. Zasada działania Emotiv Control Panel. ECP jest graficznym interfejsem uŝytkownika, który współpracuje z neurohełmem lub z EmoComposer w celu testowania napisanych aplikacji oraz sprawdzenia jakości sygnału z neurohełmu. Rys. 16. Panel stanu ECP. Na rysunku nr 16 przedstawiono panel stanu. Pokazuje on w czasie rzeczywistym stan połączenia z neurohełmem, czystość sygnału na kaŝdej z elektrod oraz zapas energii w baterii. Po prawej widać ludzką głowę z elektrodami świecącymi się na zielono, co oznacza idealne połączenie z neurohełmem. Elektrody mogą mieć 5 róŝnych kolorów: czarny brak sygnału, czerwony bardzo słaby sygnał, pomarańczowy słaby sygnał, Ŝółty średni sygnał, zielony dobry sygnał. Z tego punktu moŝemy równieŝ zarządzać profilami oraz hełmami. Rysunek nr 17 przedstawia zakładkę Expressiv Suite ECP, słuŝącą do testowania zmian mimiki twarzy. Po prawej stronie rysunku pokazano rodzaje zmian mimiki twarzy: Blink (mrugnięcie) 18
Right wink (mrugnięcie prawym okiem) Left wink (mrugnięcie lewym okiem) Look left/right (popatrz w lewo/prawo) Raise brow (podnieś brwi) Furrow brow (zmarszcz brwi) Smile (uśmiech) Clench (zacisnąć usta) Right smirk (prawy uśmiech) Left smirk (lewy uśmiech) Laught (uśmiech) Natomiast lewa strona przedstawia obraz twarzy z mimiką uŝytkownika. Rys. 17. Zakładka Expressiv Suite ECP. 19
Rys. 18. Zakładka Affectiv Suite ECP. Rysunek nr 18 przedstawia zakładkę affective suite. Jest ona odpowiedzialna za testowanie stanu emocjonalnego uŝytkownika. Linie odpowiadają stanom np. podnieceniu, znudzeniu. Kolory linii moŝna dowolnie edytować. Po lewej stronie pokazano dwa wykresy, których zakres długości moŝna dowolnie zmieniać. Rys. 19. Zakładka Cognitiv Suite ECP. Na rysunku nr 19 przedstawiono zakładkę Cognitiv Suite, która słuŝy do testowania myśli związanych z przemieszczaniem obiektów. Neurohełm pozwala na 13 róŝnych akcji: Push (pchnij) Pull (pociągnij) Lift (podnieś) 20
Drop (opuść) Left (przesuń w lewo) Right (przesuń w prawo) Rotate right (obróć w prawo) Rotate left (obróć w lewo) Rotate clockwise (obróć zgodnie ze wskazówkami zegara) Rotate counterclockwise (obróć przeciwnie do wskazówek zegara) Rotate forward (obróć do przodu) Rotate reverse (obróć do tyłu) Disappear (zniknij) Po wysłaniu odpowiedniej akcji z EmoComposera moŝna zaobserwować co dzieje się z sześcianem. Dodatkowo mamy moŝliwość trenowania kaŝdej akcji. Polega to na skupieniu się przez 8 sekund na danej czynności jaka ma być wytrenowana. 4.4. edk.dll Edk.dll jest biblioteką, która umoŝliwia budowanie aplikacji współpracujących z neurohełmem. Biblioteka zawiera wiele funkcji. PoniŜej przedstawiono tylko wybrane z nich, które zostały wykorzystane w tej pracy: EE_EngineRemoteConnect(string Host, ushort port); - funkcja ta jest odpowiedzialna za rozpoczęcie komunikacji z EmoComposer. Zwraca ona wartość inta: EDK_OK = 0; EDK_UNKNOWN_ERROR = 1; EDK_EMOENGINE_UNINITIALIZED = 1280; EDK_EMOENGINE_DISCONNECTED = 1281; EDK_EMOENGINE_PROXY_ERROR = 1282; [Emotiv.cs] EE_EngineConnect(); - funkcja odpowiedzialna za rozpoczęcie komunikacji programu z neurohełmem. Podobnie jak przy funkcji EE_EngineRemoteConnect wartością zwróconą jest int. EE_EngineDisconnect(); - funkcja odpowiedzialna za zakończenie komunikacji z EmoComposer lub hełmem. 21
System.IntPtr EE_EmoEngineEventCreate(); - funkcja tworząca nowe zdarzenie. System.IntPtr EE_EmoStateCreate(); - funkcja tworząca nowy stan dla zdarzenia. EE_EngineGetNextEvent(System.IntPtr hevent); - funkcja pobierająca kolejne zdarzenie z neurohełmu lub EmoComposer, zwraca wartość int. EE_Event_enum EE_EmoEngineEventGetType(System.IntPtr hevent); - funkcja pobierająca typ zdarzenia z neurohełmu, zwraca wartość EE_Event_enum odpowiadającą konkretnemu zdarzeniu: EE_UnknownEvent = 0, EE_EmulatorError = 1, EE_ReservedEvent = 2, EE_UserAdded = 16, EE_UserRemoved = 32, EE_EmoStateUpdated = 64, EE_ProfileEvent = 128, EE_CognitivEvent = 256, EE_ExpressivEvent = 512, EE_InternalStateChanged = 1024, [Emotiv.cs] EE_EmoEngineEventGetEmoState(System.IntPtr hevent, System.IntPtr hstate); - funkcja pobierająca nowy stan ze zdarzenia. EE_EmoEngineEventFree(System.IntPtr hevent); - funkcja zwalniająca zdarzenie. EE_EmoStateFree(System.IntPtr hstate); - funkcja zwalniająca stan. EE_CognitivAction_enum ES_CognitivGetCurrentAction(System.IntPtr hstate) funkcja pobierająca obecną akcję z neurohełmu, zwraca EE_CognitivAction_enum, który odpowiada konkretnemu zdarzeniu: neutralne = 1, przodu = 2, tylu = 4, podnies = 8, opusc = 16, lewo = 32, prawo = 64, obroclewo = 128, obrocprawo = 256, 22
obroczewskazowkami = 512, obrocprzeciwwskazowkami = 1024, obrocdoprzodu= 2048, obrocdotylu= 4096, zniknij = 8192, Host - adres IP urządzenia, na którym jest uruchomiony EmoComposer. port port, na którym nastąpi komunikacja. hevent zmienna zawierająca zdarzenie przesłane z neurohełmu/emocomposer. hstate zmienna zawierająca stan zdarzenia. Biblioteka edk.dll została napisana w Visual C++, więc w celu jej wykorzystania trzeba zastosować odpowiedni system dostosowania funkcji do kodu C#. Wykorzystano tu rozwiązanie Giuseppe Di Pietro, polegające na importowaniu potrzebnych nam funkcji np.: [DllImportAttribute("edk.dll", EntryPoint = "EE_EngineDisconnect")] public static extern int EE_EngineDisconnect();. [14] 5. Neurohełm EmotivEpoc Jak widać na rysunku 20 neurohełm składa się z 14 elektrod, które odczytują sygnał fal mózgowych. Hełm ten działa na zasadzie elektroencefalografu. Elektrody rozmieszczone na głowie mierzą zmiany potencjału elektrycznego na powierzchni skóry. Zmiany te pojawiają się w wyniku aktywności neuronów kory mózgowej. Większość elektroencefalografów sporządza wykres na podstawie tych zamian (rys. 22). [15] Rys. 20. Zdjęcie neurohełmu. 23
Rys. 21. Zdjęcie osoby z załoŝonym neurohełmem. Pomiędzy neurohełmem a zwykłym elektroencefalografem występują róŝnice. W badaniu elektroencefalografem kaŝda z elektrod musi zostać odpowiednio umieszczona na głowie i przymocowana specjalnym Ŝelem w celu uzyskania odpowiedniej przewodności oraz czystości sygnału. Elektrody neurohełmu nie wymagają juŝ stosowania Ŝelu lecz nadal muszą zostać odpowiednio umieszczone na głowie. Kolejną róŝnicą pomiędzy elektroencefalografem a neurohełmem jest brak potrzeby wykorzystania duŝej sieci elektrod w celu skalibrowania urządzenia (zwykły elektroencefalograf powinien posiadać 19 elektrod). Jednak największą zaletą urządzenia jest jego niski koszt wynoszący ok. 300$, w porównaniu z elektroencefalografem to 10-razy mniej. [16] Rys. 22. Wykres przedstawiający jedną sekundę zapisu EEG. 24
Jako iŝ neurohełm odczytuje sygnał EEG a nie czyta myśli. Sterowanie polega na tym iŝ konkretna osoba musi nauczyć neurohełm, jaki sygnał EEG jest odpowiedzialny za daną czynność. Dla przykładu dla osoby A sygnał EEG który reprezentuje obrót w lewo sześcianu, moŝe być taki sam jak dla osoby B obrót sześcianu w prawo. Nauka neurohełmu polega na tym iŝ wysyła się do neurohełmu, sygnał treningu dla odpowiedniej czynności np. pchnij. Od momentu gdy neurohełm otrzymał sygnał treningu uŝytkownik musi się skupić na danej czynności przez około 6-10 sekund. Od tego momentu neurohełm dla stanu jaki uŝytkownik utrzymał przez te 6-10 sekund, będzie odczytywał ten stan jako polecenie pchnij. II. Część praktyczna 1. Kod źródłowy W kodzie źródłowym naleŝy zwrócić uwagę na kilka komend oraz wyjaśnić co dzieje się w danym momencie w programie: Rys. 23. Okno programu odpowiedzialnego za komunikację neurochełmu z pilotem samochodu. Po wciśnięciu przycisku Połącz jest wykonywany nastepujący kod: private void button1_click(object sender, EventArgs e) 25
{ if (EE_EngineRemoteConnect(host, port)!= 0) { label1.text = "Nie moŝna nawiązać połączenia. Błąd "+Convert.ToString(EE_EngineRemoteConnect(host, port))+"."; } else { label1.text = "Nawiązano połączenie"; eevent = EE_EmoEngineEventCreate(); estate = EE_EmoStateCreate(); } } Program próbuje nawiązać połączenie z neurohełmem lub programem imitującym działanie neurohełmu. W przypadku łączenia się z programem imitującym działanie neurohełmu, naleŝy podać adres ip serwera, na którym jest uruchomiony program (w naszym przypadku następuje łączenie z maszyną lokalną i wykorzystywany jest adres 127.0.0.1) oraz port, na którym działa program (dla nas 1726). Komenda EE_EngineRemoteConnect (host, port) lub EE_EngineConnect() zwraca wartość liczbową. Dla prawidłowego połączenia zwracana jest wartość 0. Program sprawdza czy wartość zwrócona jest róŝna od zera, w przypadku kiedy nie oznacza to, iŝ nawiązanie połączenia udało się i w okienku programu pojawia się komunikat o powodzeniu połączenia. W tym samym momencie zostają stworzone przestrzenie eevent oraz estate, które będą przechowywać pobrane zdarzenia z neurohełmu. W przypadku, gdy wartość zwrócona będzie róŝna od zera nawiązanie połączenia nie udało się i w okienku programu pojawia się odpowiedni komunikat razem z kodem błędu. Kolejny przycisk Odłącz jest odpowiedzialny za zerwanie połączenia z neurohełmem lub programem imitującym neurohełm. Po jego wciśnięciu wykonywany jest następujący kod: private void button2_click(object sender, EventArgs e) { if (EE_EngineDisconnect()!= 0) { 26
label1.text = "Nie udało się rozłączyć. Błąd " + Convert.ToString(EE_EngineDisconnect()) + "."; } else { label1.text = "Rozłączono"; EE_EmoStateFree(eState); EE_EmoEngineEventFree(eEvent); timer1.stop(); } } Podobnie jak w przypadku przycisku Połącz, program sprawdza czy liczba zwrócona przez komendę EE_EngineDisconnect() jest róŝna od zera, jeŝeli jest oznacza to iŝ odłączenie od nerohełmu/programu imitującego neurohełm, nie powiodło się. W tym momencie w oknie głównym pojawia się odpowiedni komunikat z numerem błędu. W przypadku, gdy wartość zwrócona będzie równa zero nastąpi rozłączenie. Odpowiedni komunikat pojawia się na oknie głównym i następuje zwolnienie przestrzenii estate oraz eevent. Na koniec jeszcze następuje zatrzymanie timera, który jest odpowiedzialny za pobieranie kolejnych zdarzeń z programu. Kolejny przycisk ( Pobierz ) jest juŝ odpowiedzialny za pobranie zdarzeń z neurohełmu i wysłanie odpowiedniego kodu do pilota sterowania samochodu. Po naciśnięciu go wykonywany jest następujący kod: private void button3_click(object sender, EventArgs e) { stan = EE_EngineGetNextEvent(eEvent); while (stan == 0) { EE_Event_enum eventtype = EE_EmoEngineEventGetType(eEvent); if (Convert.ToString(eventType) == "EE_EmoStateUpdated") { EE_EmoEngineEventGetEmoState(eEvent, estate); float timestamp = ES_GetTimeFromStart(eState); akcja = Convert.ToString(ES_CognitivGetCurrentAction(eState)); 27
moc = Convert.ToDecimal (ES_CognitivGetCurrentActionPower(eState)); if (akcja == "neutralne" moc <= Convert.ToDecimal(0.4)) { picturebox1.location = new System.Drawing.Point(117, 83); bufor[0] = 0; wykonaj(); } if (moc > Convert.ToDecimal(0.4)) { if (akcja == "lewo") { richtextbox1.text += "Nowy stan od uzytkownika " + Convert.ToString(userID) + ". wystąpił w czasie " + Convert.ToString(timestamp) + ". Samochód ma jechać w " + akcja + ". Siła sygnału wynosi " + Convert.ToString(moc) + "." + Environment.NewLine; picturebox1.location = new System.Drawing.Point(50, 83); bufor[0] = 1; wykonaj(); } if (akcja == "prawo") { richtextbox1.text += "Nowy stan od uzytkownika " + Convert.ToString(userID) + ". wystąpił w czasie " + Convert.ToString(timestamp) + ". Samochód ma jechać w " + akcja + ". Siła sygnału wynosi " + Convert.ToString(moc) + "." + Environment.NewLine; picturebox1.location = new System.Drawing.Point(200, 83); bufor[0] = 4; wykonaj(); } if (akcja == "przodu") { richtextbox1.text += "Nowy stan od uzytkownika " + Convert.ToString(userID) + ". wystąpił w czasie " + Convert.ToString(timestamp) + ". 28
Samochód ma jechać do " + akcja + ". Siła sygnału wynosi " + Convert.ToString(moc) + "." + Environment.NewLine; picturebox1.location = new System.Drawing.Point(117, 33); bufor[0] = 8; wykonaj(); } if (akcja == "tylu") { richtextbox1.text += "Nowy stan od uzytkownika " + Convert.ToString(userID) + ". wystąpił w czasie " + Convert.ToString(timestamp) + ". Samochód ma jechać do " + akcja + ". Siła sygnału wynosi " + Convert.ToString(moc) + "." + Environment.NewLine; picturebox1.location = new System.Drawing.Point(117, 123); bufor[0] = 2; wykonaj(); } } } if (Convert.ToString(eventType) == "EDK_NO_EVENT") { label1.text = "Brak Sygnału"; } stan = EE_EngineGetNextEvent(eEvent); } } Na początku zostaje sprawdzone czy z hełmu zostało wysłane jakiekolwiek zdarzenie. Odbywa się to poprzez uŝycie komendy EE_EngineGetNextEvent(eEvent) i zapisnaie zwróconej wartości do inta o nazwie stan. Następnie wchodzimy w pętle while, która działa za kaŝdym razem, gdy otrzymujemy kolejne zdarzenie z neurohełmu. Zaraz po wejściu w pętlę zostaje sprawdzony typ zdarzenia jakie zostało pobrane przez program. Wartość ta zostaje zapisana w zmiennej eventtype. Następnie sprawdzane jest czy rodzaj zdarzenia jaki przyszedł z hełmu to EE_EmoStateUpdated. Kolejnym krokiem jest pobranie stanu ze zdarzenia, które zostało przechwycone z hełmu/programu imitującego hełm, odbywa się to przez komendę EE_EmoEngineEventGetEmoState(eEvent, estate). Następnie do zmiennej 29