1 Cel ćwiczenia Zad. 1: Sterowanie mimika twarzy Wykształcenie umiejętności posługiwania się złożonymi makrami preprocesora języka C. Stworzenie podstawowej struktury wizualizacji twarzy robota, która będzie wykorzystywana w następnych zadaniach. 2 Ogólny opis zadania Należy napisać program, który będzie w stanie przeczytać z pliku tekstowego sekwencję poleceń sterujących mimiką twarzy robota. Program będzie musiał zasymulować działanie głowy robot. Powinien on również udostępniać proste tekstowe menu, które ma umożliwiać: wczytanie z pliku tekstowego sekwencji instrukcji i jednoczesne ich wykonanie, wyświetlenie dostępnych instrukcji, zakończenie działania programu. Ponadto zakładamy, że w pliku z sekwencją poleceń możemy zastosować wszystkie udogodnienia, które dostarcza preprocesor języka C. W trakcie wczytywania i wykonywania sekwencji poleceń tuż przed jego realizacją powinna wyświetlić się pełna postać polecenia wraz z wartościami jego parametrów (patrz podrozdział 5). Jako test działania programu należy opracować sekwencję poleceń, które umożliwią ekspresję radości oraz smutku. 3 Składnia poleceń w pliku Przyjmuje się, że każde z poleceń zapisywane jest w jednej linii. Na początku występuje nazwa plecenia. Może być ona poprzedzona dowolną ilością znaków białych. Po niej następuje lista parametrów oddzielonych przecinkami. Znakiem kończącym listę jest znak średnika. Zakłada się, że program powinien obsługiwać dwa polecenia: Pauza wstrzymanie działania programu na określoną ilość czasu, Oko określa stopień otwarcia oka i szybkość przejścia do nowej konfiguracji. Usta określa wzajemne położenie dolnej i górnej wargi ust oraz oddalenie kącików ust, określa również prędkość przejścia do nowego ułożenia ust, W dalszej części jest przedstawiona składnia poszczególnych poleceń oraz przykłady ich użycia. 3.1 Polecenie Pauza Polecenie to wstrzymuje działanie programu na zadany czas. Jest on wyrażony w mikrosekundach. Pauza ilość_mikrosekund; Podana ilość mikrosekund może być wyłącznie liczbą nieujemną (a więc może być zerem). Górnym ograniczniem jest zakres wartości typu int dla kompilatora języków C/C++. Przykład użycia polecenia: 1
Pauza 100000; Powoduje ono wstrzymanie działania programu na okres 0,1 sekundy. 3.2 Polecenie Oko Określenia stan oka, tzn. zarys jego dolnej i górnej powieki. Definiuje również szybkość przejścia ze stanu poprzedniego do aktualnego. Oko id_oka, położenie_dolnej_powieki, położenie_górnej_powieki, szybkość_zmiany; Pierwsza wartość, tzn. id_oka, jest identyfikatorem oka określającym, czy polecenie odnosi się do prawego lub lewego oka. Jednak nie ogranicza ona ilość oczu. Położenie zarysu powiek jest wyrażone w jednostkach niemianowanych. Przyjmuje się, że mieści się ono w przedziale [ 100, 100]. Interpretacja tych wartości zależy od przyjętej koncepcji reprezentacji graficznej oka. Jednym z możliwych podejść jest założenie, że wartość ta odpowiada za stopień i rodzaj wypukłości kształtu powieki. Tak więc wartości ujemne mogą odpowiadać, za stopień wypukłości w dół, zaś wartości ujemne za stopień wypukłości w górę. Szybkość zmiany położenia powiek zakładamy, że wyraża procentową szybkość zmiany położenia powieki między jej dotychczasowym położeniem, a docelowym, w ciągu jednej sekundy. Zakładamy ponadto, że wartość ta jest zawsze liczbą dodatnią. Tak więc, jeśli chcemy, aby powieki osiągnęły swoje położenie docelowe w ciągu 1s, to należy zadać szybkość 100. Jeśli natomiast chcemy, aby położenie docelowe zostało osiągnięte w ciągu 0, 5s, to powinniśmy zadać wartość 200. Przykład użycia polecenia: 3.3 Polecenie Usta Oko 1, -20, 60, 150; Determinuje stan kształtu ust, tzn. zarys ich dolnej i górnej wargi. Definiuje również szybkość przejścia ze stanu poprzedniego do aktualnego. Usta położenie_dolnej_wargi, położenie_górnej_wargi, oddalenie_kacików_ust, szybkość_zmiany; Położenie zarysu ust jest wyrażone w jednostkach niemianowanych. Przyjmuje się, że mieści się ono w przedziale [ 100, 100]. Interpretacja tych wartości, podobnie jak w przypadku oka, zależy od przyjętej koncepcji reprezentacji graficznej. Analogicznie jak w przypadku oka można założyć, że wartość ta odpowiada za stopień i rodzaj wypukłości kształtu wargi. Tak więc wartości ujemne mogą odpowiadać, za stopień wypukłości w dół, zaś wartości ujemne za stopień wypukłości w górę. Oddalenie kącików usta wyrażone jest w jednostkach niemianowanych zawierających się w przedziale [ 100, 100]. Zakładamy, że wartość 0 odpowiada pozycji neutralnej. Natomiast wartości dodatnie odpowiadają za zwiększenie odległości między kącikami ust. Pozwala to stworzyć szeroki uśmiech. Wartości ujemne mają umożliwiać zmniejszenie tej odległości, co daje możliwość stworzenia wrażenia np. zdziwienia. Szybkość zmiany położenia wargi zakładamy, że wyraża procentową szybkość zmiany położenia między jej dotychczasowym położeniem, a docelowym, w ciągu jednej sekundy. Zakładamy również, że wartość ta jest zawsze liczbą dodatnią. Interpretacja prędkości zmian jest taka sama jak w przypadku oka. Przykład użycia polecenia: 2
Usta -60, -10, 20, 180; Intencją tego polecenia jest ukształtowanie ust w formie uśmiechu. Spowodowane to jest tym, że dolna warga będzie bardziej wypukła w dół niż górna. Następuje też zwiększenie odległości między kącikami usta. 3.4 Przykład użycia poleceń Poniżej przedstawiona jest przykładowa zawartość pliku z sekwencją wcześniej opisywanych poleceń. Zawiera ona również polecenia dla preprocesora, które powinny być wcześniej przetworzone przed przystąpnieniem do wczytywania właściwych poleceń. * Zakładamy, że startujemy od neutralnego wyglądu twarzy. #define SZYB_ZMIAN_DLA_USMIECHU 300 #define TRANZYCJA_OKA_USMIECH 20, 80, SZYB_ZMIAN_DLA_USMIECHU * Przejscie do fazy usmiechu Oko 0, TRANZYCJA_OKA_USMIECH; Oko 1, TRANZYCJA_OKA_USMIECH; Usta -60, -40, 30, SZYB_ZMIAN_DLA_USMIECHU; * Przez 1s utrzymujemy ekspresję twarzy niezmienioną. * Puszczenie "oczka" Oko 1, 30, 30, 300; // Zmrużenie oka Pauza 100000; // Krótka przerwa Oko 1, TRANZYCJA_OKA_USMIECH; // Powrót do stanu poprzedniego 4 Wymagania co do konstrukcji programu Program powinien być napisany w języku ISO C++11. W programie należy w odpowiedni sposób wywołać preprocesor, aby przetworzyć wczytywany plik poleceń. Ponadto w kodzie programu należy stworzyć makra, które wykorzystają konstrukcję tworzenia napisu (konstrukcje typu #x) oraz łączenia napisów (konstrukcje typu napis##x). W wersji podstawowej zadania w trakcie wczytywania pliku z instrukcjami jeżeli zostanie napotkania instrukcja, której parametry są spoza dopuszczalnego przedziału lub zostanie napotkany błąd składni, to powinna zostać wyświetlona informacja o błędzie. W tym pierwszym przypadku należy wyświetlić nazwę polecenia, którego dotyczy błąd oraz nazwę parametru i jego wczytaną wartość. Natomiast operacja egzekucji poleceń powinna zostać przerwana i program powinien wrócić na poziom obsługi swojego menu. 3
Kod programu powinien być zdokumentowany oraz zawierać diagram czynności w języku UML dla operacji czytania pliku i jego interpretacji. 5 Przykład uruchomienia i interakcji z programem Niniejszy przykład demonstruje postać menu i przykładowe komunikaty w trakcie działania programu. Zakłada się, że występujący w tym przykładzie plik ekspresja_twarzy.cmd ma identyczną zawartość z tą, która została przedstawiona w podrozdziale 3.4. SunOS 21>./interp4robface w - wczytanie z pliku sekwencji instrukcji i ich wykonanie i - pokaz dostepne instrukcje? - wyswietl ponownie menu k - koniec dzialania programu Twoj wybor (? - menu): i Pauza Oko Usta czas_us; id_oka, polozenie_dolnej_powieki, polozenie_gornej_powieki, szybkosc_zmian; pol_dolnej_wargi, pol_gornej_wargi, oddalenie_kacikow_ust, szybkosc_zmian; Twoj wybor (? - menu): w Podaj nazwe pliku: ekspresja_twarzy.cmd Wczytywanie i poczatek wykonywania pliku: Oko 0, 20, 80, 300; Oko 1, 20, 80, 300; Usta -60, -40, 30, 300; Oko 1, 30, 30, 300; Pauza 100000; Oko 1, 20, 80, 300; Koniec wykonywania pliku. Twoj wybor (? - menu): k Koniec dzialania programu. SunOS 21> _ 6 Materiały pomocnicze W podkatalogu bk/edu/zamp/zad1 jest umieszczony podstawowy zalążek programu. Zawiera on przykład użycia programu gnuplot do wygenerowania wizualizacji twarzy w wersji cyklopa. Jest tam również wstępna konfiguracja dla systemu generacji dokumentacji doxygen. 4
7 Rozszerzenia Realizacja dodatkowych poleceń odpowiadających za wizualizację brwi i ich odpowiednie sterowanie. Należy opracować sekwencję ekspresji, która pozwoli płynnie przejść między wyrazem radości, zdziwienia i smutku. Można również rozszerzyć obsługę błędów wczytywania plików z poleceniami. Należy to zrobić, tak aby w trakcie wczytywania pliku z instrukcjami jeżeli zostanie napotkania instrukcja, której parametry są spoza dopuszczalnego przedziału, to należy zgłosić informację o błędzie. Jednak program nie powinien przerywać procesu egzekucji poleceń. Powinno nastąpić przejście do następnej instrukcji. Podobnie w przypadku napotkania błędu składni w danej linii. Po jego zgłoszeniu powinna ona zostać pominięta i program powinien rozpocząć czytanie i interpretację następnej linii. Informacja o błędzie powinna objemować wyświetlenie tego co zostało wczytane w danym momencie i co było w tym miejscu oczekiwane. 5