Kurs Framsticks – krok po kroku 

Maciej Komosiński i Szymon Ulatowski

To jest nieoficjalne tłumaczenie wersji oryginalnej: Krzysztof "Filo" Gorgolewski, sierpień 2005, z poprawkami M.K., 2005-2009


O tym dokumencie

Ten kurs wprowadza krok po kroku w środowisko Framsticks. Obejmuje on podstawowe zagadnienia takie jak interfejs programu, symulacja, genetyka i ewolucja. Kurs odnosi sie też do bardziej zaawansowanych funkcji takich jak własne procedury, typy neuronów itp. Może być on używany podczas zajęć z Framsticks jak również jako samouczek. Do przeprowadzenia kursu wymagane jest środowisko Framsticks GUI (dostępne na stronie Framsticks) zainstalowane pod systemem MS Windows.

Jeżeli jesteś nauczycielem, poświęć trochę czasu by przerobić po kolei wszystkie ćwiczenia. Zalecamy też uprzednie zapoznanie sie z Podręcznikiem Framsticks. Możliwe, że zechcesz ominąć niektóre części tego kursu ze względu na twoją dziedzinę - na przykład możesz skupic się tylko na symulacji, genetyce, ewolucji, wzajemnych oddziaływaniach albo pisaniu skryptów. Informatyka, robotyka, biologia, kognitywistyka czy też filozofia wymagają poświęcenia większej uwagi różnym częściom kursu. Dobrym pomysłem jest oszacowanie na wstępie ile czasu zajmie studentom wykonanie poszczególnych zadań. Mógłbyś również wymienić rzeczy, których studenci powinni się nauczyć (albo które powinni przetestować) podczas trwania kursu. Dodatkowo możesz poprosić studentów aby przygotowali na podstawie wybranych ćwiczeń sprawozdania lub ustne prezentacje.

Jeżeli jesteś studentem czy też po prostu chciałbyć przejść ten kurs żeby nauczyć się Framsticks, polecamy abyś najpierw przejrzał Podręcznik Framsticks. Dopiero potem zacznij kurs. Dobrym pomysłem jest też poproszenie kogoś (np. koleżanki/kolegi) żeby niezależnie i równolegle wykonywał ćwiczenia tak, abyście mogli później razem dyskutować i wymieniać się pomysłami. Jeżeli pewne fragmenty będą zbyt trudne, możesz je opuścić i później przejrzeć kurs jeszcze raz. Jeżeli czegoś nie rozumiesz, zajrzyj do Podręcznika.

Pełna dokumentacja jest dostępna na oficjalnej stronie Framsticks i jest podsumowana w Podręczniku Framsticks. Ten kurs nie zastępuje dokumentacji.

  1. Podstawy
    1. Poznaj Framsticks
    2. Cel: zobaczyć parę stworzeń, ich zachowań, cech fizycznych, wzajemnych oddziaływań, itp.

      Ustawienia: uzyj Framsticks GUI dla Windows. Ustaw Simulator Parameters/Experiment/Populations/Creatures/Death na "off", włącz OpenGL (jeżeli to będzie możliwe). Ta prezentacja moze być też odegrana przy pomocy "Framsticks Theater" i pokazu "presentation".
      • Załaduj "walking.gen" i włacz symulację
      • Zasymuluj parę ciekawych stworzeń: quadruped, lizard, hopping spider, etc. (prawy klik na genotypie → Simulate → Creatures)
      • Podstawowe czynności w środowisku użytkownika:
        • przeciąganie z lewym przyciskiem: obrót kamery
        • przeciąganie z prawym przyciskiem: przesuwanie kamery
        • podwójny lewy klik: zbliżenie na organizm
        • kółko w górę/w dół: powiększenie
        • control + lewy klik: chwyć stworzenie ("manipulator")
        • shift + prawy klik: wybierz akcję
        • podwojny prawy klik: nakarm (wykonaj pierwszą akcję)
    3. Framsticks GUI
    4. Cel: Poznać interfejs użytkownika Framsticks i podstawy symulatora

      • Parametry symulatora: niektóre parametry powinny być zmienione podczas zabawy ze stworzeniami:
        • Experiment/Populations/Creatures/Death – powinno być wyłączone. W przeciwnym wypadku stworzenia mogłby niespodziewanie umierać.
        • Experiment/Parameters/Simulated Creatures – symulator automatycznie stworzy tyle stworzeń. Ustaw na 0 jeżeli nie chcesz, żeby symulator ingerował w twoje stworzenia.
      • Genotype: opis (plan budowy) stworzenia. Może być zachowany do pliku
        (GUI: menu → File → Load/Save genotypes)
      • Body&Brain Window: kliknij na genotyp, żeby zobaczyć strukturę fizyczną i połączenia neuronowe
      • Creature: stworzenie może być utworzone na podstawie genotypu
        (GUI: prawy klik na genotypie → Simulate → Creatures)
        (GUI: prawy klik na genotypie → Simulate → Kill/Delete)
      • Symulacja mechaniczna: może być MechaStick lub ODE (bryła sztywna). Zobacz ustawienie World/Simulation engine. Wypróbuj oba rodzaje symulacji, pobaw się stworkami używając manipulatora i zwróć uwagę na różnice.
    5. Nauka genetyki
    6. Cel: Nauczyć się jak zaprojektować proste stworzenie w kodowaniu 'f1'

      • Kliknij New aby stworzyć nowy genotyp
      • Wprowadź genotyp i obejrzyj rezultaty w oknie podglądu
        (Zobacz również specyfikację f1 w Podręczniku Framsticks albo w pomocy
        • Wprowadź X – pojawi się pojedyńczy segment liniowy (patyk)
        • Wprowadź kilka wiecej X'ów i przesuń kursor wzdłuż genotypu. Podgląd strukturalny podświetli odpowiadające części ciała. Kliknij na patyk, żeby podświetlić odpawiadającą mu część genotypu.
        • Rozgałęzianie: użyj nawiasów (...) i przecinków, żeby stworzyć drzewiaste organizmy. Przykład: XXX(XX,X). Zobacz jak dodatkowe przecinki wpływają na kierunki rozgałęzień: XXX(,,,XX,X)
        • Nawiasy mogą być zagnieżdżone, spróbuj: XXX(XX,X(X,X)) (przejdź wzdłuż genotypu kursorem, żeby dowiedzieć się który patyk odpowiada któremu X'owi)
        • Obrót płaszczyzny rozgałęzienia: wprowadzenie modyfikatorów R/r. Wstaw R jedno po drugim i zobacz powstała strukturę: XXX(XX,RRRX(X,X))
        • więcej modyfikatorów kształtu: Q C L – wstaw do genotypu i odgadnij jak działają. Zajrzyj do Podręcznika Framsticks w poszukiwaniu dalszych wyjaśnień. Ogólna zasada: duze/małe litery mają przeciwne znaczenie.
        • Zauważ, że czerwone tło oznacza, że genotyp jest nieprawidłowy – np. "X[", i różowe tło oznaczają błąd genotypu, który może zostać poprawiony automatycznie – np. "X()". Niektore genotypy mają poprawną składnię , ale problemy pojawiają sie podczas budowania stworzeń. Spróbuj na przykład genotypu "X[|][|]", który ma dwa identyczne mięśnie w tym samym miejscu. Jako, że jest to niepoprawne, w menu pod strzałką w obu oknach podglądu pojawi się opcja "Build problems encountered!". Wybierz ją, żeby zobaczyć wszystkie problemy konstrukcyjne.
      • Ćwiczenie 1: Zbuduj interesujacy kształt używając języka genotypu.
      • Ćwiczenie 2: Odgadnij genotyp na podstawie budowy ciała

        Rozwiązanie: zapytaj prowadzącego.

        Ćwiczenie 3: Czy potrafisz napisać inny genotyp, który opisywałby ten sam kształt?

      • Wniosek: Ograniczenia kodowania genotypu 'f1'
        • Tylko struktury drzewiaste: zamknięte pętle nie są możliwe (ale zawsze można zbudować otwartą kwadratową pętlę - spróbuj to zrobić).
        • Łodyga i jej odgałęzienia są zawsze w tej samej płaszczyźnie, taki kształt nie jest możliwy:
        (Jednakże takie kształty da sie uzyskać korzystając z innego kodowania o nazwie 'f0')
    7. Neurony
    8. Cel: dołaczyć neurony (efektory, receptory) do stworzeń

      • Opis sieci neuronowej jest wymieszany z genotypem ciała, tak jak tutaj: X[1:2]X[-1:3,0:1]X
        Każda jednostka zawarta pomiędzy nawiasami kwadratowymi to pojedyńczy neuron. Przecinki oddzielają poszczególne wejścia (połączenia) danego neuronu. W opisie każdego połączenia, liczba przed dwukropkiem jest względnym numerem połączonego neuronu (0=polączenie z samym sobą, +1=następny neuron w genotypie, -1=poprzedni). Następna liczba (po ":") to waga połączenia. W powyższym przykładzie nie wyspecyfikowano żadnej nazwy neuronu, tak więc przyjmuje się że to domyślny neuron "N". Przeanalizuj poniższe przykłady i upewnij się, ze rozumiesz je dobrze. Wprowadź je do programu jako genotyp:
        • cccXXXXX[0:0][-1:1][-1:1][-1:1][-1:1] (Łańcuch neuronów)
        • cccX[0:0]X[-1:1]X[-1:1]X[-1:1]X[-1:1] (Inne ulożenie neuronów w ciele)
        • cccX[4:1]X[-1:1]X[-1:1]X[-1:1]X[-1:1] (Zamknięta pętla)
        • cccXXXXX[0:0][0:0]X[0:0]X[0:0]X[-1:1,-2:1,-3:1,-4:1] (Wiele wejść)
      • Jest wiele typów neuronów, zajrzyj do "Simulation Parameters: Genetics: Neurons to add" żeby zobaczyć krótkie zestawienie. Przykłady:
        • X[Sin,f0:0.1]
          – "Sin" to typ neuronu (generator funkcji sinus)
          – potem musisz napisać przecinek (inna, przestarzała – i bardziej skomplikowana – notacja nie wymaga przecinka, ale lepiej używać nowszej i prostszej notacji)
          – "f0" jest atrybutem neuronu Sin – to bazowa częstotliwość dla generatora funkcji sinus
        • X[T][G][S][-3:1,-2:1,-1:1]3 receptory podłączone do neuronu
        • XX[T][-1:1][|,-1:1]receptor (sensor dotyku) → neuron → efektor (miesień)
      • Możesz zerknąć na podsumowanie kodowania f1.
    9. Kontrola mózgu
    10. Cel: monitorować i kontrolować "żywe" neurony

      • Zacznij od takiej struktury: X(X,XXRRX(X,X,,),X)
      • Dostosuj długość kończyn: X(X,lllXRRlllXlllX(lX,lX,,),X)
      • Dodaj dwa neurony mięśni. Jednemu z nich ustaw siłę (własność "p") na maksimum (1):
        X(X,lllX[|]RRlllXlllX[|,p:1](lX,lX,,),X)
      • Upewnij się, że symulator ma tak ustawione parametry:
        • Experiment/Populations/Creatures: Death jest wyłączone
        • Experiment/Populations/Creatures: Neural net simulation na "Immediate"
        • Experiment/Populations/Creatures: Performance calculation na "Immediate"
        • Experiment/Parameters: Simulated creatures jest ustawione na 0
      • Stwórz organizm na podstawie tego genotypu (Simulate → Creatures) i rozpocznij symulację (Simulation → Run). Stworzenie pojawi się na listach świata i populacji.
      • Wybierz stworzenie klikając na liście populacji. To spowoduje skojarzenie okna Body&Brain z żywym stworzeniem (a nie z genotypem) i skierowanie na nie kamery.
      • Kliknij podwójnie na neuronie #1 w oknie Body&Brain (na diagramie sieci neuronowej).
      • Małe okienko na diagramie to próbnik. Może być używany do monitorowania i zmiany sygnału. Przeciagnij gruby czarny suwak w górę i w dół. Widzisz zapewne natychmiastową reakcje mięśni – stworzenie sie porusza. Spróbuj znaleźć najlepszą sekwencję sprawiajacą, że stworzenie będzie poruszało się do przodu.
      • Dodaj wskaźnik prędkości do listy populacji: prawy klik na liście populacji → "Show columns" → "Velocity". Teraz możesz odczytać aktualną prędkość podczas sterowania stworzeniem.
      • kliknij na czerwonej etykiecie hold żeby uwolnić wyjście neuronu.
    11. Budowanie mózgu
    12. Cel: Sprawić, żeby stworzenie poruszało się samodzielnie

      Użyjemy neuronu "Sin" (generatora funkcji sinus) żeby uzyskać sygnał sterujący mięśnia.

      • Dołącz nowy neuron Sin:
        X[*][N][Sin,f0:0.1,-1:0.2][N,-1:1,-3:-0.5](X,lllX[|]RRlllXlllX[|,-2:-0.5,p:1](lX,lX,,),X)
          Wyjaśnienie:
        • [Sin,f0:0.1] to generator funkcji sinus o domyślnej częstotliwosci 0.1. Częstotliwość wyjściowa zależy też od wejść neuronu Sin.
        • -2:0.5 oznacza "podłacz do neuronu przed poprzednim (-2), waga 0.5"
        • [*] to neuron dający stały sygnał o wartości (1).
      • Stwórz organizm i wybierz go z listy. On się rusza!
      • Tym razem próbniki będą pokazywały zmieniajace się sygnały: sterujący mięśniem oraz sterujący sinusem. Dodaj pierwszy próbnik do neuronu przed mięsniem. Kliknij i przytrzymaj lewy przycisk myszy na etykiecie "1x" i przesuń w prawo. To zwiekszy rozdzielczość czasową wyświetlanego sygnału i sprawi, że będzie bardziej czytelny.
      • Dodaj drugi próbnik do neuronu przed generatorem Sin. Przesuwaj powoli suwak w góre i w dół. W taki sposób mozesz kontrolować częśtotliwość generatora, ponieważ generator Sin zmienia częstotliwość zgodnie z sygnalem wejściowym. Obserwuj pierwszy próbnik.
      • Ćwiczenie 1: Ustaw Experiment/Populations/Creatures: Performance sampling period = 1000. Ożyw na nowo stworzenie. Dobierz optymalny wzorzec sterujący (dający najwiekszą prędkość). Mozesz zmieniać zarówno częstotliwość generatora, jak i stałą wartość (drugie wejście dla neuronu z przodu mięśnia).
      • Dodaj próbnik do drugiego mieśnia. Zmieniając sygnał spróbuj sprawić, żeby stworzenie skręcało w lewo i w prawo.
      • Ćwiczenie 2: Spraw by stworzenie skręcało w stronę jedzenia. Możesz zacząć od tego genotypu:
        X[*][Sin][N,-1:44,-2:3](X[S],,lllllX[|,3:1]RRlllllXlllllX[|,-3:-0.5,p:1](lX,lX,,),,X[S][N,-1:0,-4:0])
        Nowe receptory [S], umieszczone po bokach, będą generowały różne sygnały gdy w pobliżu (z lewej lub z prawej strony) znajdzie sie jedzenie. Czy potrafisz wykorzystać tę informację aby poprawnie ustawić w kontrolnym (środkowym na rysunku) neuronie? Spróbuj dobrać wagi tak, żeby stworzenie się nie przewracało kiedy zakręca!
      • Ćwiczenie 3: Nasz poprzedni organizm nie był zbyt stabilny podczas skrętów. Stwórz idealnego pożeracza pożywienia dodając dwa sensory zapachu do Back Crawler'a z walking.gen!
      • Ćwiczenie 4: Weź Right Angler'a z walking.gen i zobacz, jak jego prędkość zależy od częstotliwości generatora sinusa. Następnie, używając neuronu-sensora "Energy", spowoduj by Right Angler poruszał się szybko kiedy ma dużo energii, i stopniowo zwalniał aż do śmierci. Potem zaimplementuj odwrotne zachowanie.
    13. Komunikacja
    14. Cel: Nauczyć stworzenia komunikować się ze sobą

      Ten podrozdział nie jest przetłumaczony na polski. Zajrzyj do angielskiego tutoriala.

  2. Ewolucja
    1. Optymalizacja ewolucyjna
    2. Cel: Niech ewolucja usprawni twoje stworzenie

      W poprzednich ćwiczeniach próbowaliśmy ręcznie stworzyć szybko poruszające się stworzenia. Zobaczmy czy algorytm ewolucyjny Framsticks moze być użyty do tego celu.

      • Usuń wszystkie genotypy i stworzenia (albo nawet uruchom od nowa program, jeśli dużo wcześniej zmieniałeś)
      • dodaj następujący genotyp:
        X[*][Sin][N,-1:1,-2:1](X,lllX[|]RRlllXlllX[|,-2:-0.5,p:1](lX,lX,,),X)
        (ten genotyp został uproszczony przez usuniecie wejścia generatora funkcji sinus)
      • Ustaw parametry symulacji:
        • Experiment/Populations/Creatures: Death: włączone
        • Experiment/Populations/Creatures: Neural net simulation: "After stabilization" (i tak samo Performance calculation)
        • Experiment/Populations/Creatures: Performance sampling period: 1000
        • Experiment/Parameters: Gene pool capacity: 20
        • Experiment/Parameters: Simulated creatures: 1
        • Experiment/Parameters/Selection: Crossed over: 0 (dlaczego nie chcemy krzyżowania?)
        • Experiment/Parameters/Fitness: Velocity: 1 (pozostałe na 0)
        • Genetics/f1/Morphology: wszystkie na 0 (nie chcemy mutować ciała)
        • Genetics/f1/Neuron net: "Add/remove neuron" i "Add/remove neural connection" na 0, reszta na 1
      • Otwórz wykres. Przejdź do "Interface Options → simulator charts", wybierz "Genotypes: Fitness: Average Fitness", kliknij Apply, kliknij Add chart. Wybierz "Genotypes: Fitness: Maximal Fitness", kliknij Apply, kliknij Add chart. Zamnknij okno (naciśnij ESC), i pokaż okno wykresów naciskając [Shift-F6]. Pomyśl jak będą wyglądały te wykresy, wyjaśnij dlaczego.
      • Rozpocznij symulację. Obserwuj okno "gene pool". Możesz posortować kolumnę "velocity" żeby przekonać sie czy ewolucja robi postępy. Naciśnij [F9] żeby ukryć okna i przyspieszyć ewolucję ([Shift-F4] pokaże okno z genotypami). [F4] przywróci domyślne rozstawienie okien.
      • Jest wiele parametrów wpływających na algorytm. Zajrzyj do "parameters reference" w dokumentacji Framsticks.
      • Spójrz na wykresy. Porównaj średnie i maksymalne dopasowanie (prędkość). Czy twoje oczekiwania się sprawdziły?
      • Po jakimś czasie, kiedy nie zauważasz polepszeń, ustaw "Delete genotypes" na "Only the worst". Obserwuj wykresy. Co się stało?
      • Kto zwyciężył? Czy stworzenie powstałe w wyniku ewolucji jest szybsze od tego, które zaprojektowałeś ręcznie?
      • Zobacz, które fragmenty aryginalnego genotypu zostały zmienione przez ewolucję. Jakie znaczenie mają te zmiany?
      • Ustaw "Genetics: f1: morphology: add/remove a modifier" na 1. Ustaw "Excluded modifiers" tak, żeby zawierały wszystkie modyfikatory oprócz "L" oraz "l". Kontynuuj ewolucję sprawdzając, czy zmienia się budowa organizmów.
      • Spróbuj zgadnąć jakie byłyby wyniki ewolucji po zmianie Experiment/Populations/Creatures: Neural net simulation: na "Immediate". Wyczyść pulę genów i populacji i sprawdź swoje przypuszczenia eksperymentalnie. Ustaw wszystkie parametry odpowiednio, wyczyść wykresy, uruchom ewolucję i porównaj wyniki z poprzednimi.
    3. Wysokie struktury, projektowanie i ewolucja
    4. Cel: porównać ręczne projektowanie i ewolucję w budowaniu wysokich stworzeń

      • Spróbuj zbudować jak najwyższe stabilne stworzenie używając kodowania 'f1'. Nie używaj neuronów, chodzi tylko o ciało. Zapisz ten genotyp do pliku, e.g. "my_tall.gen".
      • Wyjdź z programu i uruchom go ponownie (żeby się upewnić, że wszystkie parametry mają domyślne wartości).
      • Ustaw parametry symulacji:
        • Experiment/Populations/Creatures: Death: włączona
        • Experiment/Populations/Creatures: Neural net simulation: "Off"
        • Experiment/Parameters: Gene pool capacity: 20
        • Experiment/Parameters: Simulated creatures: 1
        • Experiment/Parameters/Fitness: Vertical position: 1 (pozostałe: 0)
      • Dodaj prosty genotyp X.
      • Rozpocznij symulację. Obserwuj okno gene pool. Możesz dodać kolumnę "Vertical position" (prawy klik na liście genotypów) i ją posortować, żeby zobaczyć czy ewolucja robi postępy. Naciśnij [F9] żeby ukryć okna i przyspieszyć ewolucję ([Shift-F4] pokaże okno z genotypami). [F4] przywróci domyślne rozstawienie okien.
      • Kto zwyciężył? Czy stworzenie powstałe w wyniku ewolucji jest lepsze od tego, które ręcznie zaprojektowałeś?
      • Spróbuj odgadnąć jakie byłyby wyniki ewolucji po zmianie Experiment/Populations/Creatures: Neural net simulation: na "Immediate". Wyczyść pulę genów i populacji i sprawdź swoje przypuszczenia eksperymentalnie. Ustaw wszystkie parametry odpowiednio, wyczyść wykresy, uruchom ewolucję i porównaj wyniki z poprzednimi.
    5. Optymalizacja według dwóch kryteriów
    6. Cel: odkryć wielokryterialną optymalizację i związane z nią zagadnienia

      • Teraz będziesz musiał ewoluować stworzenia, które będą zarazem wysokie i proste. Spójrz na ustawienia Experiment/Parameters/Fitness. Musisz zmaksymalizować "Vertical position" i jednocześnie minimalizować liczbę części ciała ("Body parts").
      • Zasugeruj funkcję oceny. Pomyśl o wartościach "vertical position" i "body parts". Wprowadź swoje wagi dla tych kryteriów, wciśnij Apply, i sprawdź wzór Experiment/Gene pools/Genotypes/Fitness.
      • Jakie są wady tego sposobu obliczania oceny?
      • Co to jest normalizacja ("normalization")? Spróbuj odgadnąć znaczenie Experiment/Parameters/Fitness/Criteria normalization.
      • Przeprowadź eksperyment ewolucyjny. Czy rezultaty są zadowalające? Jeżeli masz problemy z uzyskanie interesujacych wyników, ustal co jest przyczyną i jakie są sposoby przezwycieżenia tej sytuacji. Powtórz eksperyment parę razy i porównaj wyniki z kolegami. Kto ma najlepsze wysokie i zarazem proste stworzenie? Rozważ obydwa kryteria i porównaj stworzenia, które najlepiej weewoluowały.
  3. Ćwiczenia dodatkowe
    1. Kodowanie 'f0'
      • Przeczytaj rozdział o kodowaniu 'f0' w Podręczniku Framsticks.
      • Zbuduj następujące kształty: kwadrat, sześcian, tetrahedron, graniastosłup trójkątny formemny. Najpierw narysuj te kształty na kartce papieru i znajdź współrzędne.
        Potem zaproponuj inne proste, ale interesujące figury i je zbuduj.
      • Zbuduj prostą sieć neuronową z trzech neuronów połączonych w jednej lini (Touch, N, Bending muscle). Zmień umiejscowienie (embodiment) sensora dotyku (Touch) w ciele (przydziel go do różnych części - "Parts").
      • Sprawdź genotypy 'f0' utworzone przez konwersje z 'f1'. Wprowadź proste genotypy 'f1' (ciał i ciał z mózgami), tak jak w sekcji I.4, wciśnij "Apply" za każdym razem i przeanalizuj pole "Conversion: f0 genotype".
    2. Ewolucja z użyciem kodowania 'f0'
      • Powtórz eksperymenty II.2 i II.3, ale tym razem używając kodowania 'f0'. Żeby tego dokonać opróżnij pulę genów i populacji, uruchom symulację i wybierz najprostszy genotyp 'f0' z listy do wyboru. Najpierw zastanów się jakie będą różnice pomiedzy zoptymalizowanymi organizmami w kodowaniu 'f0' i 'f1'. Następnie sprawdź czy mialeś rację.
    3. Inne definicje eksperymentów
    4. Cel: zobaczyć jak symulator framsticks może być kontrolowany przez skrypty definicji eksperymentów

      • Zrestartuj program. Ustaw Experiment/Experiment definition na "neuroanalysis". Naciśnij "Apply". Przeczytaj opis (Description). Zamknij okno parametrów. Załaduj "walking.gen". Otwórz okno parametrów i naciśnij "Initialize experiment". Zamknij okno parametrów i uruchom symulację. Zamknij okno podglądu świata, żeby przyspieszyć symulację. Niczego nie dotykaj, aż symulacja sama sie nie zakończy. Następnie zbadaj niektóre genotypy i obejrzyj ich pola Genotype/Info. Omów jak można wykorzystać informacje wyliczone w tym eksperymencie i jakie są znaczenia poszczególnych wartości.
      • Zrestartuj program. Ustaw Experiment/Experiment definition na "reproduction". Naciśnij "Apply". Przeczytaj opis (Description) uważnie. Naciśnij "Initialize experiment". Zamknij okno i uruchom symulację. Otwórz okno Messages. Obejrzyj symulację.
        1. Czy możesz stwierdzić jaka jest maksymalna liczba żywych stworzeń?
        2. Czy jest możliwe aby wszystkie stworzenia wymarły?
        3. Czy możesz powiedzieć czy można przewidzieć ile stworzeń się pojawi?
        4. Czy w takiej konfiguracji dokonują sie jakieś usprawnienia ewolucyjne?
        5. Jaka jest różnica pomiędzy tą konfiguracją a eksperymentami w sekcji II?
      • Zrestartuj program. Ustaw Experiment/Experiment definition na "learn_food". Naciśnij "Apply". Przeczytaj opis (Description) uważnie. Naciśnij "Initialize experiment". Zamknij okno i uruchom symulację. Zbadaj wpływ parametru Experiment/Parameters/Share knowledge na zachowanie systemu. Sprawdź również parametr Experiment/Parameters/Energy/Food placement.
  4. Skrypty
  5. Cel: nauczyć się używania FramScript i zrozumieć jego wagę i potencjał

    1. Typy wartości i konwersje
    2. Otwóż okno konsoli (Console) we Framsticks GUI. Wprowadź następujące polecenia, jedno po drugim:

      ? 2+3
      ? 2.0+3
      ? 2+3.0
      ? "a"+2
      ? ""+2+3
      ? 2+"12"
      ? "2"+12
      ? Math.time
      ? Math.time%1000
      ? (0+Math.time)%1000
      ? (0+Math.time)%1000
      
      
      Sprobuj wyjaśnić jak wyliczono wyniki.

      Teraz spróbuj odgadnąć jaki będzie wynik a potem sprawdź czy miałeś rację:

      ? 2.0*3
      ? 2*3.0
      ? 1+2.0*3.0
      ? 1.0+2*3
      ? 2*3.0+0.0
      ? (2*3.0)+0.0
      ? 2*(3.0+0.0)
      ? 7+"3"+4
      ? 7+("3"+4)
      ? 2*3.5
      ? 2*3.99
      
      

      Notacja szesnastkowa może okazać sie przydatna:

      ? 0xA
      ? 0xff+10
      ? 5+"0xf0"
      ? "0xf0"+5
      
      

      A teraz zapoznaj się z tablicami (dwie ostatnie linie są celowo blędne):

      ? ["aa",4,"5"][0]
      ? ["aa",4,"5"][1]
      ? ["aa",4,"5"][2]
      ? ["aa",4,"5"][Math.random(3)]
      ? ["aa",4,"5"][3]
      ? [aa,4,"5"][0]
      
      

      A teraz parę wartości i typów, ale przy pomocy zmiennych:

      var a;  a=5;  Simulator.print(a);
      var a;  a=5;  a=a+3.0;  Simulator.print(a);
      var a;  a=5;  a=3.0+a;  Simulator.print(a);
      var a;  a=5;  a="abc"+a;  Simulator.print(a);
      var a=5;  Simulator.print("abc"+(0.0+a));
      var a=["aa",4,"5"];  Simulator.print(a[2]+3);
      
      

      Typy ponownie, teraz z użyciem operatora typeof żeby sprawdzac typ wyrażenia podczas wykonywania programu:

      ? typeof(5)
      ? typeof(3.0)
      ? typeof(5+3.0)
      ? typeof(3.0+5)
      ? typeof("some text")
      ? typeof("some text"+3)
      ? typeof(3+"0")
      ? typeof(null)
      
      

      Porównania, konwersje i wykrywanie null ("brak wartości"):

      ? 4==4.0
      ? 4=="4"
      ? 4=="5"
      ? 4<"5"
      ? null==0
      ? null==0.0
      ? typeof(null)==typeof(0.0)
      
      

      Mała zagadka – wyjaśnij wyniki:

      ? 44<"5"
      ? "44"<5
      
      ? "blabla"!=0
      ? 0=="blabla"
      

      Więcej informacji o FramScript można znaleźć tutaj.

    3. Przykładowy skrypt
    4. Teraz spójrz na ten fragment kodu. Przeanalizuj każdą linię tak, abyś na pewno zrozumiał jak działa.

      World.wrldsiz = 150;                        //zrób duży świat
      GenePools.clearGroup(0);                    //usuń wszystkie genotypy w pierwszej puli genów
      Populations.clearGroup(0);                  //usuń wszystkie stworzenia w pierwszej populacji
      Simulator.import("encoding_f1_best.gen", 2); //załaduj genotypy z pliku
      GenePools[0][7].genotype="X";               //tego genotypu nie ma w tym pliku...
      GenePools.group = 0;                        //wybierz pierwszą pulę genów
      Populations.group = 0;                      //wybierz pierwszą populację
      var i,x,y;
      for (i=0; i<30; i++)
      {
        GenePools.genotype=i;                     //wybierz i-ty genotyp (od 0 do 29)
        var c=Populations.createFromGenotype();   //i utwórz na jego podstawie stworzenie
        x = 20+(i%10)*9;                          //wylicz współrzędne docelowe...
        y = 30+(i/10)*20;                         //discover how the values of x and y are computed!
        c.moveAbs(x - c.size_x/2, y - c.size_y/2, c.pos_z);  //i przesuń środek stworzenia
      }
      

      Jeżeli odkryłeś jak są wyliczane współrzędne na podstawie numeru stworzenia (zmienna i), teraz upewnij się, ze symualcja jest zatrzymana, wklej ten fragment kodu do okna konsoli i wykonaj go. Zobacz jak są rozmieszczane stworzenia: powiększ okno podglądu świata na pełen ekran i obróć kamerę.

      Jak widzisz ten fragment kodu automatyzuje wiele czynności.

    5. Własne funkcje oceny
    6. Rzuć okiem na wzór Experiment/Gene pools/Genotypes/Fitness. Jest to wzór automatycznie aktualizowany po każdej zmianie kryteriów optymalizacji. Możesz jednak stworzyć funkcję oceny lepiej dostosowaną do własnych potrzeb używając if ... then, zmiennych (var) tymczasowych, pętli, itp. Najpierw jednak musisz się nauczyć czegoś o polach wykorzystywanych w funkcji oceny. We Framsticks GUI, wybierz z menu "Help" "FramScript: reference". Wybierz kontekst "Fitness formula" oraz klasę "this". Są to metody i wartości (atrybuty).

      Następnie wybierz w kontekście globalnym klasę "Math". Teraz czas na własne eksperymenty! Zaimplementuj następujące funkcje oceny. Dla każdej z nich wyjaśnij jej znaczenie i sprawdź w praktyce jak działa. Weź pod uwagę skrajne warunki (dzielenie przez zero, pierwiastki kwadratowe z wartości ujemnych, itp.).

      1. Liczba Joints + 0.01 * liczba neuronów
      2. Pierwiastek kwadratowy z prędkości
      3. (Ilość Parts + ilość Joints) podzielona przez ilość połaczeń neuronowych
      4. Dopasowanie warunkowe: Jeżeli stworzenie ma mniej niż 5 segmentów to dopasowanie jest wprost proporcjonalne do wzrostu. W przeciwnym wypadku dopasownie to wysokość pomniejszona o 0.1*(ilość segmentów minus 5).
      5. (bardziej skomplikowane zadanie) Dopasowanie to ilość połączeń (Joints) podzielona przez objętość (size_x*size_y*size_z) modelu stworzonego z Geno.

      Zobacz więcej materiałów na temat pisania skryptów – znajdziesz tam pełen przegląd dostępnych kontekstów, klas i metod.

    7. Własne klasy neuronów
      1. Pisanie większych kawałków kodu we FramScript może ułatwić Ci Framclipse.
      2. Znajdź podkatalog "scripts" w katalogu instalacyjnym Framsticks. Spójrz na rozszerzenai plików i ich zawartość. Następnie wyświetl plik "threshold.neuro". Pliki *.neuro maja trzy części: preambułę (podstawowy opis neuronu), kod (oddzielony znakami ~ ) oraz właściwości (parametry neuronu). Przeanalizuj ten plik uważnie i zobacz jak działa neuron "threshold". Następnie uruchom program i użyj tego genotypu
        X[*][Thr,-1:1,t:-0.2,hi:0.3,lo:0.8]
        żeby go przetestować.
      3. Teraz spójrz na źródło neuronu noisy (plik noisy.neuro). Czy potrafisz wytłumaczyć jak on działa? (krótki opis tego neuronu znajduje się też w rozdziale poświeconym Framsticks książki Artificial Life Models in Software). Wymyśl jakiego genotypu możnaby użyć do przetestowania tego neuronu, a potem sprawdź to eksperymentalnie.
      4. Odkryj jakich procedur (metod) mozesz używać we FramScript. We Framsticks GUI, wybierz "Help" i "FramScript: reference". Poświeć chwilę, żeby przejrzeć interesujace Cię klasy. Sprawdź klasę "Math", jej metody i wartości ("attributes").
      5. Skopiuj i zachowaj noisy.neuro pod inną nazwą (exa.neuro), ale nadal w tym samy katalogu. Otwórz plik i zmień nazwę neuronu modyfikując odpowiednia linię: "name:ExA" (Nazwy neuronow muszą się rozpoczynać wielką literą). Pełną nazwą powinno być "Exercise A". Teraz spróbuj zmodyfikować funkcję go() tak żeby wyjściem neuronu była funkcja sinus. Zachowaj plik, uruchom ponownie program i sprawdź okno Messages w poszukiwaniu błędów. Jeżeli wszystko jest w porządku stwórz genotyp, żeby przetestować swój neuron ExA. Jeżeli coś nie będzie działać popraw błędy albo poproś o pomoc prowadzącego.
      6. Teraz pora na prawdziwe ćwiczenie (a). Musisz zaprojektować neuron, który na wyjściu daje sygnał przedstawiony na rysunku. Twój neuron ExA powinien mieć tylo jeden parametr (t) określajacy długość okresu tego wzorca (ilość kroków symulacji, po której wzorzec sie powtórzy). Zamiast uruchamiać ponownie program za każdym razem, zeby załadować nowy kod neuronu, spróbuj kliknąć Simulation Parameters/User scripts/Reload neuron definitions.
      7. Jeżeli Ci się powiodło rozwiąż następujące trzy zadania. Dla każdego stworz oddzielny plik (exb.neuro, exc.neuro, exd.neuro). W ćwiczeniu (d), będziesz potrzebował dwóch parametrów, zeby sprecyzować długości (w krokach symulatora) wysokiego i niskiego poziomu wyjścia. W niektórych zadanich będziesz musiał użyć funkcji init(), żeby zaincjalizować niektóre pola. Zapytaj prowadzącego, jeżeli nie mozesz sobie z czymś poradzić albo pomiń problem, jeżeli nie możesz uzyskać pomocy.
      8. Przed Tobą jest jeszcze 5 wyzwań! Najpierw skonstruuj neuron wygładzający sygnał wejściowy poprzez uśrednianie wartośći aktualnego wejścia z dwoma poprzednimi. Użyj sumy ważonej a nie pojedyńczych wejsć.
      9. Następnie zbuduj neuron który zwraca na wyjściu maksymalną wartość spośród swoich wejść. Zaprojektuj odpowiednią sieć neuronową, żeby go przetestować.
      10. Potem zbuduj neuron, który mnoży wartość jednego wejścia przez wartość drugiego i wynik wystawia na wyjście.
      11. Następnie zbuduj komórkę pamieci. Pierwszym wejściem będzie wartość do zachowania a drugim sygnał kontrolny (jeżeli jest mniejsz od zera komórka zapamietuje stan pierwszego wejścia). Jeżeli sygnał kontrolny wynosi zero lub wiecej komórka pamięci zwraca zapamiętany wcześniej sygnał.
      12. W końcu, zbuduj neuron, który na wyjściu będzie dawał sygnal obu wejść na raz używając jednego kanału. Twój neuron powininen liczyć sumę ważona obu wejści i podawać ją na wyjście jako (zawsze) dodatnią wartość na kanale pierwszym i zawsze ujemną wartość na kanale drugim. Potem możesz użyć neuronu ChSel żeby wyciągnąć jeden kanał z wielokanalowego wyjścia.

      Zauważ, że pomimo, że robimu zwykłe neurony nic nie stoi na przeszkodzie, żeby projektować własne sensory (funkcja go() może wykorzystywać informacje o świecie i innych stworzeniach). Można też tworzyć efektory, ale w większości przypadków będzie to wymagało zmiany definicji eksperymentu.

    8. Własne makra
      • Znajdź podkatalog "scripts" w katalogu instalacyjnym Framsticks. Przyjrzyj sie zawartości plików z rozszerzeniem ".script". Są bardzo podobne do plików *.neuro, nieprawdaż? Też maja segment "code:"
      • Teraz uważnie przeanalizuj pliki "neuroclsreport.script", "foodcircle.script", "creaturescircle.script" i "gallery.script". We Framsticks GUI znajdź Simulation Parameters/User scripts. Możesz uruchamiać skrypty i zobaczyć jak działają.
      • Pamiętasz przykład w rozdziale IV.2? Może zostać zachowany w pliku *.script i uruchomiony jednym kliknięciem.
      • Jeżeli chcesz trochę poeksperymentować i zmodyfikować parę plików .script, najpierw zachowaj je pod inną nazwą. Następnie zmodyfikuj źródła i uruchom ponownie program, zeby przetestowac zmainy. Możesz też testować makra wklejając ich kod w oknie konsoli. Kiedy skończysz zaimplementuj następujące makra:

      1. ustaw wszystkie stworzenia z populacji #0 na planie kwadratu (wyślij wiadomość jeżeli nie będzie czego ustawiać)
      2. tak jak powyżej, ale najwyższy organizm powinien stać na środku
      3. ustaw je w lini, według wzrostu
      4. zwiększ poziom wody o +0.5
      5. wydrukuj raport – wyświetl wszystkie obiekty (genotypy, stworzenia) we wszystkich pulach genów i populacji, wraz z nazwami puli
      6. do każdego genotypu dodaj do puli genetycznej 10 mutantów. Oryginalne genotypy powinny pozostać niezmienione, a nazwy mutantów powinny się składać z kolejnych liczb doklejanych z przodu nazwy pierwotnych stworzeń
      7. potrząśnij stworzeniami! dla wszystkich grup stworzeń, dla każdego stworzenia, dla wszystkich jego MechPart, dodaj niewielką liczbę do jego prędkości. Dużo wygodniej będzie Ci obserwować w akcji tę procedurę, jeśli umieścisz jej źródło jako funkcję w definicji eksperymentu, np. żeby wywoływała się co 200 kroków symulacji.
      8. (zadanie zaawansowane) tak jak powyżej, ale dla wszystkich MechParts z neuronem Touch dodaj niewielką wartość do MechPart.vz

      • Jeśli z jakiegoś powodu chciałbyś zapisywać jakieś dane z symulacji w zwyczajnym pliku, możesz użyć obiektu File. Obejrzyj scripts\neurof0html.script; nie musisz rozumieć dokładnie jak ten skrypt działa, ale zwróć uwagę na to jak wykorzystano tam obiekt File. Możesz uruchomić ten skrypt i zobaczyć plik jaki został utworzony w katalogu scripts_output.
    9. Interfejs lini poleceń (Command-line interface - CLI)
    10. Cel: zapoznać się z Framsticks CLI i nauczyć sie jak go używać do automatyzacji eksperymentów

      1. Pobierz CLI i przygotuj go do pracy.
      2. Uruchom "frams". Wprowadź "lm". Zajrzyj do pliku "frams.ini" , zwróc uwagę na funkcje init() i naucz się jak makra są powiązane z implementacjami funkcji.
      3. Poeksperymentuj z następującymi makrami: im, sa, st, lg, lc, qu.
      4. Zauważ, ze możesz wprowadzać polecenia tak jak w IV.1.
      5. załaduj plik "walking.gen", ustaw pulę genów na 20 (używając FramScript), uruchom symulację aż nie zostanie zbadanych 100 stworzeń (używajac pętli while),i zachowaj wyniki do "walk2.gen".
      6. Utwórz plik "cmd.txt" z poleceniami, których używałeś w poprzednim ćwiczeniu. Uruchom interfejs lini poleceń Windows lub Linux (cmd.exe or sh), i wprowadź:
        frams < cmds.txt
        
      7. Naucz sie jak używać parametrów w lini poleceń – wprowadź
        frams --help
        
        a potem, na przykład,
        frams "? 2+3" "lo walking.gen" "lg" "qu"
        
      8. Spraw, żeby neuroanalysis.expdef badało wszystkie genotypy z walking.gen, a potem zachowaj pulę genów ("sa walk-analyzed.gen"). Jeśli używasz definicji eksperymentu innej niż standard.expdef, musisz ją ustawić w argumencie programu w ten sposób: frams "ex neuroanalysis". Nie zapomnij zaincjalizować eksperymentu.
      9. Utwórz plik "cmds-neu.txt" z poleceniami użytymi w poprzednim ćwiczeniu, wyjdź z programu i użyj go w trybie wsadowym.
    11. Własne definicje eksperymentów
    12. Zajrzyj do plików scripts/*.expdef, wybierz prosty expdef, zobacz jak są zaimplementowane zdarzenia "onCośtam", zachowaj expdef pod inną nazwą, zmodyfikuj, uruchom ponownie GUI i przetestuj swoje zmiany. Obejrzyj proste learn_food.expdef i generational.expdef. Jeżeli powiodło Ci się wykonanie poprzednich zadań, jesteś teraz w stanie implementować własne definicje eksperymentów. Oto kilka pomysłów:

      1. Wylicz distance Genotypu jako różnicę pomiędzy miejscem urodzenia a miejscem śmierci.
      2. Wylicz dopasowanie jako wysokość najwyższej części ciała, uśrednioną w czasie życia (mierzoną w zadarzeniach onUpdate).
      3. Sprzątanie: w momencie kolizji dwóch organizmów poza środkiem planszy, większy z nich jest przesuwany na środek planszy. Jeśli to miejsce jest zajęte (kolizja z czymś istniejącym, użyj LiveLibrary.creatBBCollisions), umieszczamy go coraz wyżej.
      4. Walka o zasoby (arena): stworzenia rodzą się w dwóch przeciwległych końcach areny ita która jest w stanei pokryć największą powierzchnie ma uzyskuje lepszy współczynnik dopasowania (oceny).
      5. Pościg i ucieczka: dwie pule genów, dwie przeciwstawne funkcje oceny, jedna grupa stworzeń ewoluuje, żeby uciec, a druga ją goni.
    13. Własny pokaz Framsticks (Theater show)
    14. Zajrzyj do plików scripts/*.show, wybierz sobie prosty pokaz, sprawdź jak są zaimplementowane zdarzenia "onSomething", zachowaj plik pod inną nazwą, zmodyfikuj go, uruchom ponownie program prezentacji i przetestuj swoje zmiany. Musisz używać zarejestrowanej wersji programu prezentacji, żeby testować własne prezentacje.

    15. Własny styl OpenGL
    16. Zajrzyj do plików 3dobj/*.style. Kontunuuj tak jak poprzednio. Przeczytaj kurs (prezentację) o skryptach - zawiera on analogiczne przykłady. Musisz zarejestrować Framsticks GUI, żeby używać nowych styli OpenGL. Przeczytaj też "jak stworzyłem Spooksticks".

 
 
 
On the forum: