Maszyna stanów - dziwne zachowanie

Tematy związane z tworzeniem dużych aplikacji. Zaganiednia dotyczące architektury oraz zasad tworzenia optymalnych rozwiązań.
Awatar użytkownika
fajfi
Posty: 185
Rejestracja: 28 sty 2004 00:00
Wersja środowiska: LabVIEW 2010
Lokalizacja: Wrocław

Maszyna stanów - dziwne zachowanie

Post autor: fajfi »

Cześć,
popełniłem niewielki program dla studentów do wizualizacji przebiegu podstawowych funkcji.
Wykorzystałem maszynę stanów. To dopiero przymiarka do właściwego programu, więc proszę się nie gniewać za kilka prowizorycznych rozwiązań.
Idea jest taka: użytkownik wybiera jaką funkcję chce oglądać, otwiera się zakładka z parametrami typowymi dla tej funkcji, ustawia te parametry i ładuje je - pojawia się wykres.
Następnie może podać nowe parametry i ponownie ładuje, po czym do starego wykresu dołącza nowy itd.
(wgrywanie nowych wykresów działa tylko w obrębie funkcji tego samego typu).
Gdy mu się znudzi jeden rodzaj funkcji, kończy przeglądanie odpowiednim przyciskiem i wybiera inną funkcję itd.
Zdążyłem zrobić jedynie funkcję liniową i kwadratową.
A teraz co jest źle:
Włączam program. Wybieram np. funkcję liniową, bawię się parametrami i wgrywam kolejne wykresy, zatrzymuję oglądanie. Następnie przechodzę do funkcji kwadratowej i program się zawiesza.
W drugą stronę jest tak samo: wybieram funkcję kwadratową, przechodzę do liniowej i znowu zawieszka.
Zupełnie nie rozumiem zachowania tego programu, wydaje się, że wszystko powinno być ok.
Czy ktoś z kolegów lub koleżanek może mnie oświecić w tej materii? Co robię źle?
Pozdrawiam
Fajfi
Załączniki
wykresy-wizualizacja.vi
(24.08 KiB) Pobrany 386 razy
Awatar użytkownika
Ender
Posty: 137
Rejestracja: 02 cze 2005 00:00
Wersja środowiska: LabVIEW 2009
Lokalizacja: Cieszyn

Re: Maszyna stanów - dziwne zachowanie

Post autor: Ender »

Mam nadzieję że nie zamieszam za bardzo :)
Event jest obsługiwany tylko w momencie jak nastąpi zdarzenie mu przypisane - tutaj naciśnięcie przycisku. Póki jakiegoś nie naciśniesz, pętla while w której jest event jest wykonywana. A skoro jest ona wewnątrz innej pętli while, to ta zewnętrzna pętla będzie się wykonywała póki nie naciśniesz przycisku zakończenia tej pętli z eventem. dlatego nie przechodzisz z jednej funkcji do drugiej, bo przyciski zmiany funkcji są obsługiwane tylko w 'nic', a żeby tam przejść musisz zakończyć pętlę while w stanie w którym akurat jesteś. A tego nie zrobisz póki nie naciśniesz 'Zakończ' - wtedy program się 'odwiesi'.
Na początek wyrzuć obsługę wszystkich przycisków do osobnej pętli while która będzie wykonywana równolegle do maszyny stanów, a dane z niej przekazuj do maszyny stanów np zmiennymi lokalnymi. W samej maszynie stanów wyrzuć pętle while jeśli nie są niezbędne - zamiast czekać na ich zakończenie możesz przecież przechodzić do tego samego stanu a dopiero jakieś wydarzenie z pętli eventów może zainicjalizować przejście do innego stanu.
-Czy orał pan już kiedyś morskie fale?
Colon rzucił mu chytre spojrzenie.
-Nie złapie mnie pan na taki numer, sir - rzekł - Wszyscy wiedzą, że konie by potonęły.
Leonard umilkł na chwilę i przestroił swój mózg na Radio Colon ....
Awatar użytkownika
skrzatswat
Posty: 21
Rejestracja: 13 lut 2012 16:26
Wersja środowiska: LabVIEW 2011

Maszyna stanów - dziwne zachowanie

Post autor: skrzatswat »

Witam,

Twoje rozwiązanie nie do końca mi się podoba (ale to oczywiście tylko i wyłącznie moje osobiste zdanie ;] nie lubię za dużo event structures) :) Mogę zaproponować coś o wiele prostszego, proszę:
States.ctl
(5.47 KiB) Pobrany 424 razy
test.vi
(16.68 KiB) Pobrany 439 razy
Bardzo łatwo jest rozbudować ten program o dodatkowe rodzaje wykresów.
Ostatnio zmieniony 01 mar 2012 19:24 przez skrzatswat, łącznie zmieniany 3 razy.
Obrazek
PiDi
Posty: 641
Rejestracja: 31 gru 2010 01:36
Wersja środowiska: LabVIEW 2017
Lokalizacja: Katowice

Re: Maszyna stanów - dziwne zachowanie

Post autor: PiDi »

Zacznijmy od tyłu:
skrzatswat pisze:Twoje rozwiązanie nie do końca mi się podoba
A ja powiem, że bardzo mi się nie podoba i mam nadzieję, że fajfi się nie obrazi ;) Swego czasu próbowałem już naprawiać czyjś program, w którym event structy były porozrzucane dość swobodnie po maszynie stanów, i od tamtego czasu alergicznie reaguję na takie rozwiązania. Jak zresztą sam widzisz, fajfi, twój program jest ciężki w debugowaniu, a przy okazji:
fajfi pisze:To dopiero przymiarka do właściwego programu, więc proszę się nie gniewać za kilka prowizorycznych rozwiązań.
To się zwykle nie udaje. Prowizorka, która nie daj Boże działa, zwykle staje się ostatecznym rozwiązaniem... Dopóki nie trzeba w końcu tego poprawić i w praktyce napisać wszystkiego od początku, czego sobie nie życzymy?

Jeśli chodzi o to wieszanie się, to zobacz przykład:
Wieszanie.vi
(6.62 KiB) Pobrany 338 razy
Jeśli aktualnie czekasz w strukturze event i wywołasz zdarzenie, które jest obsługiwane w jakiejś innej strukturze, to aplikacja się zawiesi. Event zostanie przechwycony i LabVIEW będzie czekało na jeg obsłużenie. A jako, że w konfiguracji eventa "Wieszajacy guzik" (obrazek niżej) jest ustawiona opcja Lock Front Panel, to front panel pozostaje już zablokowany na wieki, bo nie jesteśmy w tym miejscu, gdzie możemy obsłużyć tego konkretnego eventa. Zauważ, że odznaczenie tej opcji sprawia, że aplikacja zadziała. Czyli niby można by "naprawić" twój program, odznaczając we wszystkich eventach tę opcję, ale... Ech, chyba już pokazałem, że dużo ewentowych strukturów jest ZŁE? :ymdevil:
event.jpg
Rozwiązanie skrzatswata wygląda już ładnie, a ja sobie też machnąłem swoje dla ćwiczenia, więc wrzucam:
funkcje.zip
(24.15 KiB) Pobrany 359 razy
ObrazekObrazekObrazekObrazek
Awatar użytkownika
fajfi
Posty: 185
Rejestracja: 28 sty 2004 00:00
Wersja środowiska: LabVIEW 2010
Lokalizacja: Wrocław

Re: Maszyna stanów - dziwne zachowanie

Post autor: fajfi »

Cześć,
bardzo dziękuję za tak szybkie i merytoryczne odpowiedzi.
Właśnie zauważyłem, że do tej pory myliłem pojęcia "stanu" i "akcji", i bez przerwy je mieszałem.
Przyczyna zawisania mojego kodu okazała się banalna, ale z drugiej strony cieszę się, z tej pomyłki, gdyż zapewne jeszcze długo miałbym mętlik w głowie.
PiDi pisze:A ja powiem, że bardzo mi się nie podoba i mam nadzieję, że fajfi się nie obrazi ;)
Zapewniam, że Fajfi się nie obrazi, bo nie ma o co :) - kod po prostu był zły i muszę go poprawić.
PiDi pisze:To się zwykle nie udaje. Prowizorka, która nie daj Boże działa, zwykle staje się ostatecznym rozwiązaniem... Dopóki nie trzeba w końcu tego poprawić i w praktyce napisać wszystkiego od początku, czego sobie nie życzymy?
Widocznie nie wyraziłem się jasno. Pisząc "prowizorka", miałem na myśli symulację czy kod testowy, na którym chciałem zobaczyć działanie samego pomysłu. Oczywiście potem zastąpiłbym to rozwiązaniem docelowym. Całkowicie się zgadzam z Twoją opinią o prowizorce.

Oba rozwiązania są piękne (lecą pochwały). W takich chwilach uważam, że programowanie to nie tylko "technika", ale w dużym stopniu "sztuka" :)
Przyznaję jednak, że rozwiązanie skrzataswata bardziej do mnie przemawia. Wydaje się dużo prostsze.
Przy okazji chciałem zapytać: w kodzie występują dwa "typy" enum constatnt. Jeden jest zwykły, a drugi ma taki czarny trójkącik w lewym górnym rogu. Czym właściwie się one różnią?
Pozdrawiam
Fajfi
P.S. Mam nadzieję, że nie zostanę skrzyczany przez moderatora? :)
Doszedłem do wniosku, że tak drobne pytanie nie zasługuje na nowy wątek...
Załączniki
typy.jpg
typy.jpg (3.44 KiB) Przejrzano 7957 razy
PiDi
Posty: 641
Rejestracja: 31 gru 2010 01:36
Wersja środowiska: LabVIEW 2017
Lokalizacja: Katowice

Re: Maszyna stanów - dziwne zachowanie

Post autor: PiDi »

Rozwiązanie skrzataswiata jest faktycznie nieco prostsze, ja chciałem wyraźnie oddzielić stan aplikacji od wybranej funkcji. Czy to ma sens, to już zależy od koncepcji rozwoju tej aplikacji - może się okazać dużym udogodnieniem przy dodawaniu kolejnych funkcjonalności.

Czarny kwadracik na stałych w LV 2011 się pojawił i oznacza, że element jest podpięty do typedefa.
ObrazekObrazekObrazekObrazek
ODPOWIEDZ