Zatrzymanie pętli while

Jeśli masz coś do powiedzenia w sprawie LabVIEW napisz. Tutaj są tematy, których nie można uściślić do innych działów.
paczu
Posty: 10
Rejestracja: 03 lip 2012 18:08
Wersja środowiska: LabVIEW 2010

Zatrzymanie pętli while

Post autor: paczu »

Witam wszystkich.
Mam do Was pytanie, bo walczę z bardzo prostym programikiem i wydaje mi się że próbuję zrobić rzecz niemożliwą. Chciałbym się upewnić czy rzeczywiście się tak nie da czy po prostu nie wpadłem na pomysł jak to zrobić.

Programik analizuje dane z pliku i wyświetla je na wykresie.
Wciśnięcie przycisku "Wczytaj dane" uruchamia event, który wczytuje dane funkcją Read From Spreadsheet File. Następnie dane te, w pętli while, są przetwarzane i prezentowane na wykresie. Za pomocą trzech zadajników można wpływać na sposób przetwarzania danych, co na bieżąco widać na wykresie.

Wszystko niby ładnie działa dopóki nie spróbuję wczytać kolejnego pliku z danymi. Wiadomo, najpierw trzeba zatrzymać pętlę while.
I tu jest moje pytanie: czy da się zrobić to tak, aby kolejne wciśnięcie przycisku "Wczytaj dane" pozwalało na wczytanie i analizę kolejnego pliku bez konieczności wcześniejszego zatrzymywania pętli przyciskiem STOP?

kolego/koleżanko paczu witaj na forum. Następnym razem staraj się nazywać nowe tematy bardziej opisowo. Pitol
may
Posty: 96
Rejestracja: 20 lut 2012 12:30
Wersja środowiska: LabVIEW 2014
Lokalizacja: Katowice / Ruda Śląska

pętla while

Post autor: may »

To co próbujesz zrobić na pewno nie jest niemożliwe, jest to jeden z najbardziej typowych rodzajów programów pisanych w LabVIEW.
Nie pokazałeś nam kodu, więc ciężko jest mi dokładnie pokazać palcem "o, tu jest źle".
Czytając ten opis nasuwa się, że zastosowałeś po prostu złą architekturę programu.
W takim przypadku najlepiej będzie skorzystać z maszyny stanu.
Jeżeli nie wiesz dokładnie jak budować maszyny stanu, wpisz w Google "LabVIEW maszyna stanu", lub "LabVIEW state machine", jest bardzo wiele tutoriali i opisów.
Dobrym miejscem z którego można zacząć jest otwarcie sobie nowego VI z gotowym szablonem maszyny stanu (File -> New... , rozwijamy drzewko i szukamy "Standard State Machine").

Jak (ideowo) miała by działa taka maszyna stanu?
1. Po uruchomieniu idź do stanu init, gdzie możesz wykonać wszystkie swoje procedury przygotowujące. Następny stan -> czekaj na reakcję użytkownika
2. stan czekania na reakcję użytkownika. Tu znajduje się struktura event która obsługuje interakcję użytkownika z interejsem i przekierowuje do odpowiedniego stanu w zależności co użytkownik kliknął.
3. Stan "wczytaj pliki". Wczytuje pliki, następny stan -> wyświetl wyniki
4. stan "wyświetl wyniki". Wyświetla wyniki, następny stan -> czekaj na reakcję użytkownika
5. stan stop. w tym stanie zatrzymujesz program (Czyli stopujesz pętlę while wewnątrz której działa maszyna stanu). Do tego stanu powinno się trafić jeżeli użytkownik naciśnie przycisk stop, albo wystąpi jakiś błąd w aplikacji.

Powyższa struktura opisuje (bardzo uproszczoną oczywiście) architekturę maszyny stanu, która powinna robić to do czego zmierzasz. Architekturę taką bardzo łatwo rozszerzyć o kolejne stany, a więc łatwo rozbudować funkcjonalność programu. (Hmm, potrzebuje nie tylko wyświetlać wyniki a również je analizować? Myk, dodaję kolejny stan, reszty nie ruszam, wszystko działa.)
Spróbuj napisać swoją aplikację w postaci właśnie maszyny stanu, jak będziesz miał dalsze problemy problemy to pisz, postaramy się pomóc.

A jeżeli twoja aplikacja to jest maszyna stanu i właśnie sobie myślisz "czemu on mnie traktuje jak głąba, przecież tak to właśnie mam napisane, nie działa mi tylko jakaś mała rzecz a on mi wszystko tłumaczy jak dziecku", to wybacz, po prostu nie wyczytałem tego z twojego opisu problemu, następnym razem załącz też kod :P
Obrazek
Garreth
Posty: 74
Rejestracja: 28 gru 2011 14:13
Wersja środowiska: LabVIEW 2011

pętla while

Post autor: Garreth »

Ja kolegę zrozumiałem że ma strukturę (od zewnątrz): while, event, while. Jeśli tak, to tego wewnętrznego while'a musisz tak przerobić, aby się zatrzymał po wykonaniu obliczeń (co prawda podejrzewam, że tego while'a da się zastąpić inną strukturą no pętlą for). Ale tak gdybać można w nieskończoność, więc pokaż kod, a pokombinujemy:)
may
Posty: 96
Rejestracja: 20 lut 2012 12:30
Wersja środowiska: LabVIEW 2014
Lokalizacja: Katowice / Ruda Śląska

Zatrzymanie pętli while

Post autor: may »

Ja też mniej więcej tak zrozumiałem dlatego od razu proponuję maszynę stanu. While i obliczenia w evencie to bardzo, bardzo zły pomysł. Taki program to podręcznikowy przykład zastosowania state machine. Ja wiem, że to jest mały i prosty program i może się wydawać, że nie ma potrzeby stosowania "aż" maszyny stanu, ale pisanie nawet małych programów zgodnie z "kanonem", umożliwiając sobie łatwe późniejsze modyfikacje i rozbudowę to naprawdę słuszna idea.
Obrazek
paczu
Posty: 10
Rejestracja: 03 lip 2012 18:08
Wersja środowiska: LabVIEW 2010

Re: Zatrzymanie pętli while

Post autor: paczu »

Dziękuję za szybkie odpowiedzi i sugestie.
Przyznam się, że o maszynie stanu słyszę pierwszy raz. Książka, z której korzystam, jest mocno okrojona i nie ma w niej ani słowa o maszynie stanu (D. Świsulskiego).
Poszperałem w necie i rzeczywiście jest to ciekawe narzędzie, aczkolwiek nie koniecznie dobre do mojego zadania.
Intuicyjnie stworzyłem strukturę zbliżoną do maszyny stanu. W rzeczywistości jest to pętla while a w niej case. konkretne case'y uruchamiane są eventami.
(w pierwszym poście chciałem jak najmniej gmatwać opis dlatego uprościłem go do minimum, to był błąd).

poniżej jeden z case'ów, a w nim programik prezentujący dane wraz z trzema innymi parametrami na wykresie
fragment.jpg
W poszczególnych case'ach są niezależne programiki, które nie wymieniają między sobą danych. Wszystkie z nich (case'y a w nich programy) uruchamiane są eventami po wciśnięciu przycisku "wczytaj dane". Po wczytaniu danych z pliku, są one "obrabiane" i prezentowane na wykresach.

i teraz o co mi chodzi? na powyższym przykładzie: wczytanie danych i wprowadzenie parametrów powoduje wygenerowanie wykresu. chciałbym, po wczytaniu danych, móc na bieżąco zmieniać te parametry i widzieć te zmiany na wykresie (i tak właśnie się dzieje) ale próba wczytania kolejnego pliku do analizy bez uprzedniego zatrzymania pętli while powoduje zawias.

Pewnie pojawi się pytanie: "a jakiż to problem wcisnąć przycisk stop i następnie wczytać kolejny plik?" Niby słuszne ale chciałbym, jeśli to możliwe, uniknąć takiego rozwiązania.
may
Posty: 96
Rejestracja: 20 lut 2012 12:30
Wersja środowiska: LabVIEW 2014
Lokalizacja: Katowice / Ruda Śląska

Zatrzymanie pętli while

Post autor: may »

Uwaga ogólna: jeżeli wrzucamy jakiś kod, to bardzo wygodnie jest to zrobić w postaci code snippetu. Jak uzyskać code snippet? Wchodzimy na diagram blokowy zaznaczamy wszystko, klikamy Edit -> Create VI Snippet from Selection. LabVIEW zapisze nam kod naszego VI w postaci obrazka. Możemy zapytać: OK, fajnie, ale jaką to przewagę ma nad zwykłym print-screenem? Otóż tak przygotowany obrazek możemy przeciągnąć do okna LabVIEW, co spowoduje wczytanie kodu aplikacji z obrazka. Taka mała, bardzo użyteczna magia.

A co do twojej aplikacji to: Ugh, wybacz, będę nudny ale dalej polecam maszynę stanu. Twój program to naprawdę książkowy przykład użycia tej architektury (A co do książki którą tam wymieniłeś: jeżeli nie ma w niej czegoś tak podstawowego dla LabVIEW jak maszyny stanu to... cóż, sugeruję sięgnąć po jakieś inne pozycje). Mam jakieś tam pomysły jak można by zrobić żeby ten twój program działał, ale są absolutnie paskudne, gwałcą okropnie dataflow aplikacji i jest to metoda w stylu "użyjmy taśmy klejącej a jeżeli nie zadziała to użyjmy więcej taśmy klejącej".
Jeżeli miałbyś problemy z przerobieniem aplikacji na maszynę stanu (to naprawdę jest mniej roboty niż Ci się wydaje!) to wrzuć kod (jako VI albo jako właśnie code snippet :P ) a postaram się pomóc.
Obrazek
paczu
Posty: 10
Rejestracja: 03 lip 2012 18:08
Wersja środowiska: LabVIEW 2010

Zatrzymanie pętli while

Post autor: paczu »

ok, spróbuję zrobić z tego maszynę stanu, tylko nie za bardzo widzę w czym taka architektura będzie lepsza. Jednym ze stanów, który nastąpi po naciśnięciu przycisku "wczytaj dane" będzie powyższy case. Czy w maszynie stanu będziemy mogli zrobić coś więcej w sprawie zatrzymania pętli while?
Nie znam tej architektury i głównie dlatego spróbuję
may
Posty: 96
Rejestracja: 20 lut 2012 12:30
Wersja środowiska: LabVIEW 2014
Lokalizacja: Katowice / Ruda Śląska

Re: Zatrzymanie pętli while

Post autor: may »

paczu, Chciałem tu napisać długi wywód co jak i dlaczego, ale potem przypomniałem sobie, że sam krzyczę na ludzi którzy nie zamieszczają kodu. Więc postanowiłem zrobić demko architektury maszyny stanu (a nawet prawie taki szablon z którego możesz skorzystać).

W pliku zip wrzucam VI z tym demkiem (zip dlatego że są tam dwa pliki - vi i ctl z definicją typu stanów maszyny).
Obrazek tylko po to, żeby post był bardziej kolorowy :P

Mam nadzieję, że bez problemu połapiesz jak wsadzić wszystkie swoje funkcje obliczeniowe w ten szablon który przygotowałem.
I pamiętaj, w żadnym ze stanów nie nie tworzymy pętli while!
To właśnie był Twój główny problem, architektura Twojego początkowego programu to była prawie maszyna stanu, tylko w jednym ze stanów umieściłeś pętle z której nie potrafiłeś wyjść.
Jaka jest przewaga takiej architektury? Jest ich kilka:
Przede wszystkim jest czytelna dla każdego kto siedzi już trochę w LabVIEW (tak, wiem, dla początkujących może nie być taka oczywista), łatwo sprawdzić co nie działa i ławo to naprawić.
Po drugie, rozbudowanie jej o kolejne funkcjonalności jest bardzo proste. W definicji typu określającej stany maszyny dodajemy nowy stan, przekierowujemy do nowego stanu w miejscach gdzie tego potrzebujemy i ewentualnie dodajemy nowe eventy w strukturze obsługującej interakcję z użytkownikiem.
Po trzecie: sprawdź jak obciąża procesor twoja aplikacja. Powinna w całości zająć jeden rdzeń, czyli na dwurdzeniowym procesorze powinieneś spodziewać się obciążenia w okolicach 50%. Oczywiście, można by się trochę ratować dodaniem tam opóźnień, ale to dalej nie jest dokładnie to co byśmy chcieli uzyskać. Natomiast ta sama aplikacja napisana jako maszyna stanu będzie zajmować czas procesora tylko w momencie faktycznego liczenia i powinieneś się spodziewać w zasadzie niezauważalnego obciążenia procesora (ok. 1%).

Spróbuj wrzucić w ten szablon swoje funkcje, jak będziesz miał problemy, pisz. Nauczenie się takich kilku podstawowych architektur (a maszyna stanu może być użyta w 90% nie-bardzo-rozbudowanych programów) jest naprawdę bardzo ważne jeżeli myślimy o jakimś takim bardziej profesjonalnym zajęciem się LabVIEW. A nawet jeżeli to jest tylko jakiś studencki projekt i nigdy więcej nie zamierzasz działać w LabVIEW, to i tak zawsze możesz zaskoczyć prowadzącego naprawdę "ładnie" i "zgodnie z kanonem" napisaną aplikacją :p
Załączniki
statemachine demo.zip
(21.53 KiB) Pobrany 427 razy
statemachine demo.png
Obrazek
paczu
Posty: 10
Rejestracja: 03 lip 2012 18:08
Wersja środowiska: LabVIEW 2010

Zatrzymanie pętli while

Post autor: paczu »

niezgodność wersji :( da się to zapisać w wersji zgodnej z LV 2010?
may
Posty: 96
Rejestracja: 20 lut 2012 12:30
Wersja środowiska: LabVIEW 2014
Lokalizacja: Katowice / Ruda Śląska

Re: Zatrzymanie pętli while

Post autor: may »

Wybacz, nie popatrzyłem na twoją wersję LV.
Załączniki
statemachine demo v.10.0.zip
(16.59 KiB) Pobrany 454 razy
Obrazek
paczu
Posty: 10
Rejestracja: 03 lip 2012 18:08
Wersja środowiska: LabVIEW 2010

Zatrzymanie pętli while

Post autor: paczu »

super! działa elegancko. rzeczywiście kluczem do sprawy jest pozbycie się pętli while. program przelicza wszystko jednorazowo w pętli for po każdej zmianie parametrów wejściowych. Dziękuję bardzo za pomoc.

Póki co, uruchomiłem ten jeden programik, pozostaje jeszcze umieścić pozostałe i w związku z tym mam jeszcze jedno pytanie.
Tak jak już wcześniej pisałem mam kilka (5) różnych, niezależnych programów do przeliczania danych z plików. Każdy z nich znajduje się na osobnej zakładce. W każdym z nich jest możliwość wczytania pliku, wprowadzenia pewnych współczynników oraz wygenerowania wykresu.
Czy w moim programie mogę użyć 5 maszyn stanu umieszczonych w poszczególnych case'ach tak, aby przełączając zakładkę konkretnego programu uruchamiać odpowiedni case a wraz z nim jedną maszynę stanu? Czy raczej będzie to zbrodnia karalna i lepiej spróbować upchać wszystko w jednej maszynie?
may
Posty: 96
Rejestracja: 20 lut 2012 12:30
Wersja środowiska: LabVIEW 2014
Lokalizacja: Katowice / Ruda Śląska

Zatrzymanie pętli while

Post autor: may »

Zbrodnia karalna to z pewnością nie będzie, ale to dość nietypowa architektura. Pomyśl czy jakichś części twojego aplikacji nie da się uwspólnić dla tych twoich podprogramów. Czy na pewno potrzebujesz 5 różnych kawałków kodu wczytujących plik? Albo czy każdy z podprogramów musi mieć własny wykres na który będzie wypluwał dane? Może wystarczy ci jeden stan do wczytywania danych, 5 różnych stanów dane te obrabiających i jeden stan rysujący dane na wykresie? Rozumiem, że teraz pewnie masz już ten kod napisany i zrobienie 5 niezależnych programów może wydać Ci się szybsze, ale pomyśl gdybyś miał napisać następny program w podobnej architekturze (albo do tej twojej aplikacji dodać następny, 6 podprogram). Będziesz musiał dublować dużo kodu, a tak to dodasz tylko jeden stan obrabiający odpowiednio dane nie ruszając w zasadzie stanów do interakcji z użytkownikiem, stanów do czytania itd. Albo wyobraź sobie, że w przyszłości zechcesz dodać funkcjonalność zapisania przetworzonych danych do pliku. W tej multi-maszynie będziesz musiał napisać ten sam kod 5 razy, a jak za pół roku okaże się, że np. może jednak trzeba zapisać do innego formatu pliku to będziesz musiał szukać (bo do tego czasu zapomnisz co jak i gdzie) wszystkich miejsc gdzie piszesz do pliku i każde z nich poprawiać. A można to było zrobić tylko w jednym miejscu. Pewnie wydaje Ci się, że uczepiłem się jakiegoś jednego schematu i wszystkich pragnę przekonać, że on jest przecudowny i jedyny słuszny. A gdzie tam! To twoja aplikacja, napisz ją jak tylko masz ochotę:p Ja tylko staram się pokazać zalety przemyślenia architektury przed napisaniem programu :)
Obrazek
paczu
Posty: 10
Rejestracja: 03 lip 2012 18:08
Wersja środowiska: LabVIEW 2010

Zatrzymanie pętli while

Post autor: paczu »

rzecz w tym, że jest to mój pierwszy kontakt z maszyną stanu i wydaje mi się że mogę polegnąć przy próbie umieszczenia wszystkiego w jednej takiej strukturze. Podstawienie jednego programiku do szablonu było proste i na pewno łatwiej mi będzie powielić tą czynność dla pozostałych 4 niż przebudować wszystko od nowa. Nie zliczę już ile razy robiłem wszystko od nowa, ciągle zmieniały się pomysły, struktury, rozwiązania. Teraz program już by działał prawie idealnie ...no właśnie, prawie. A w zasadzie to czemu by nie spróbować od nowa jeszcze raz :-B ale w takiej sytuacji raczej będę jeszcze potrzebował trochę pomocy.
Garreth
Posty: 74
Rejestracja: 28 gru 2011 14:13
Wersja środowiska: LabVIEW 2011

Zatrzymanie pętli while

Post autor: Garreth »

Kolejny zadowolony użytkownik maszyny stanu:)

Jak zrobisz 5 maszyn stanu i każda "przełączana" pomiędzy zakładkami, to znowu przyjdzie Ci się zmierzyć z problemem zatrzymania pętli while (no chyba, że inaczej to sobie wyobraziłeś) i będzie to dość nieoptymalne.
May ale ten schemat jest przecudowny. Czy jedyny słuszny to już można kłócić, bo jeszcze można zastosować obiekty, ale nie ma co życia komplikować nowemu użytkownikowi:)
paczu
Posty: 10
Rejestracja: 03 lip 2012 18:08
Wersja środowiska: LabVIEW 2010

Zatrzymanie pętli while

Post autor: paczu »

zobaczymy, w pierwszej kolejności, tak dla ćwiczeń, zrobię to według swojej koncepcji. a potem postaram się wszystko wsadzić do jednej maszyny. mam nadzieję, że jakoś ruszy
ODPOWIEDZ