Skocz do zawartości

[Python 3.7] Zawieszanie się przy łączeniu z baza danych


mnak24

Pomocna odpowiedź

Witam!

Zanim opiszę problem, to postaram się przybliżyć projekt. 

Buduję "robota mobilnego" na projekt na studiach, na którym następnie będę robił inżynierkę. Robot będzie sterowany przez internet. Dlaczego przez internet? Ponieważ pojazd będzie musiał działać niezależne od odległości od operatora, czyli bt, wifi i rc odpadają.

Nie będę się tu skupiał na wszystkich założeniach, ale z grubsza ma to wyglądać tak, że ja siedząc w dowolnym miejscu steruję robota przez laptopa z dostępem do internetu. Robot posiada RPI z modemem usb, które będzie służyło do odbierania informacji o sterowaniu. RPI przekazuje informacje do Arduino, które na podstawie tychże informacji steruje silnikami. Arduino potrzebne jest, aby zamontować także czujniki odległości, które w przypadku błędu w RPI zatrzymały robota, gdy ten dojedzie do przeszkody.

Postanowiłem użyć własnego hostingu, aby przez jego bazę danych MYSQL przesyłać wartości wysterowania silników (L/P). Problem pojawia się, gdy uruchamiam program, ponieważ po n-tym połączeniu z BD, program zawiesza się na 1-5 sekund, co w przypadku sterowania może okazać się katastrofalne w skutkach (wjazd do głębokiej kałuży/stawu, wtargnięcie na ulicę).

Czy ktoś z użytkowników forum ma pomysł, jak można ten problem rozwiązać? W załączniku wklejam kod programu, doszedłem że zawsze zawieszą się w linii 8, czyli przy metodzie connect. Łączenie przed pętlą nie daje możliwości odświeżania danych, program wypisuje tylko te, które były aktualne w momencie jego uruchomienia, czyli wszelkie zmiany nie są wtedy możliwe.

 

import pymysql as p
import time

i=0

while(True):
        i += 1
        print(i)
        polaczenie=p.connect('hosting1924411.online.pro','00203498_sterowanie','robotcontrol','00203498_sterowanie')
        manage = polaczenie.cursor()
        query = 'SELECT * FROM `sterowanie`'
        manage.execute(query)
        row = manage.fetchone()
        print(row[1])
        print(row[2])
        polaczenie.close()

python mysql.png

Edytowano przez mnak24
Link do komentarza
Share on other sites

Po pierwsze, bądź uprzejmy zamieszczać kody programu za pomocą odpowiedniego narzędzia a nie jako zdjęcie, bo następnym razem w odpowiedzi dostaniesz zdjęcie odpowiadającego zamiast pomocy. Nie na każdym urządzeniu da się Twoją słitaśną focię odczytać (przykładowo komórka z mniejszym ekranem). Przy okazji wrzucaj może trochę więcej kodu, bo jeśli doskonale wiesz w którym kawałku kodu jest błąd a reszta jest tajna - powinieneś sam go umieć poprawić.

Możesz wyjaśnić, dlaczego bombardujesz bazę danych kolejnymi połączeniami? Po co connect za każdym odczytem? Co jaki czas robisz te odczyty? Użycie relacyjnej bazy danych do odczytu pojedynczego wiersza z dwoma polami to bardzo dziwny pomysł - jeśli chcesz przynieść dwie bułki ze sklepu na rogu to nie używasz osiemnastokołowej ciężarówki z naczepą, bo na 100% nie będzie szybsza niż własne nogi.

Jeśli to jakiś współdzielony hosting a nie Twoja prywatna maszyna (fizyczna, a nie VPS) to się nie dziw, bazy danych tak działają. Ciesz się że admin jakiś niemrawy, bo u mnie po 1000 połączeniu w tym tempie dostałbyś bana na godzinę (nie personalnie ode mnie, a od samego serwera MySQL).

Jeśli to prywatna maszyna z którą możesz zrobić co chcesz - zrób to porządnie (jakiś prosty serwer socket, może być za SSL-em, serwujący dane np. z pamięci wspólnej, z którym się raz łączysz a ponowne połączenie robisz dopiero po zerwaniu tego które już masz).

Link do komentarza
Share on other sites

Zaktualizowałem kod w poprzednim poście.

Z bazą łączę się każdorazowo, ponieważ gdy zastosuję ten kod:

import pymysql as p
import time

i=0

polaczenie=p.connect('hosting1924411.online.pro','00203498_sterowanie','robotcontrol','00203498_sterowanie')
manage = polaczenie.cursor()
query = 'SELECT * FROM `sterowanie`'

while(True):
        i += 1
        print(i)
        manage.execute(query)
        row = manage.fetchone()
        print(row[1])
        print(row[2])

to w wyniku otrzymuję tylko wartości takie, jakie baza posiadała w momencie wykonania połączenia. Na przykład:

I. W bazie mam wartości left: 123 i right: -211

II. Odpalam program, prawidłowo wyświetla wartości 123 i -211

III. Dokonuję zmiany w bazie mysql, np. na left: 74 i right: 178

IV. program nadal wyświetla mi wartości 123 i -211, gdzie chcę, aby wyświetlił 74 i 178

Do sterowania robota potrzebuję zmieniać te wartości, a pętla ma wyłapywać te zmiany na bieżąco.

 

Jeśli te zacięcia są po stronie serwera, to myślę o postawieniu apacha2 na własnym komputerze i użycie hamachi do stworzenia pseudo lanu dla komputera sterującego i RPI.

Link do komentarza
Share on other sites

9 godzin temu, mnak24 napisał:

wyniku otrzymuję tylko wartości takie, jakie baza posiadała w momencie wykonania połączenia.

Nic dziwnego, ten typ tak ma. Właśnie natknąłeś się na przedziwne zjawisko zwane cache i powinieneś się już w tym momencie zorientować, że MySQL nie nadaje się do Twoich zastosowań. I nie są to żadne "zacięcia" tylko normalny objaw pracy serwera bazy danych.

9 godzin temu, mnak24 napisał:

myślę o postawieniu apacha2 na własnym komputerze

Czytałeś "Alicję w Krainie Czarów"? Zegarka nie smaruje się masłem, choćby to było najlepsze masło.

Przede wszystkim: podstawowy błąd w założeniach. Internet nie jest medium o nieskoczenie wielkiej prędkości przekazywania informacji. Wręcz przeciwnie: prędkość jest skończona i - prawdę mówiąc - niezbyt wielka. Sekundowe opóźnienie to wcale nie tak dużo... szczególnie w przypadku TCP/IP i możliwości zgubienia pakietu (również o prawdopodobieństwie różnym od zera, i to sporo różnym). Łazikiem na Marsie też chciałbyś sterować bezpośrednio? Tam opóźnienia są jeszcze większe...

Jeśli już się upierasz przy Internecie, to wyeliminuj wszystkie możliwe opóźnienia (łącznie z tymi, które wprowadza protokół HTTP i kobylasty Apache, najlepiej również te z TCP/IP).

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

@mnak24 daj znać czy jesteś koniecznie związany z tą technologią - masz jakieś konkretne wytyczne z uczelni oprócz tego, że pojazd ma być sterowany przez Internet? Tak jak wspomniał @ethanak - w tej chwili stosujesz mało optymalne rozwiązania dla tego typu projektu i bez zmiany technologii nie uzyskasz dużo lepszych efektów. 

Link do komentarza
Share on other sites

Nie jestem, mysql to w zasadzie jedyny sposób komunikacji przez internet jaki nam przedstawiono. Mam wytyczne samego robota i co dalej muszę dojść sam. Mam też pomysł, aby użyć programów do zdalnej obsługi Rpi przez internet, tylko nie wiem czy takie rozwiązanie pozwoli mi na użycie gamepada usb do sterowania.

Link do komentarza
Share on other sites

8 godzin temu, mnak24 napisał:

, mysql to w zasadzie jedyny sposób komunikacji przez internet jaki nam przedstawiono

Nie chcę być niegrzeczny ani podważać autorytety Twoich nauczycieli,ale MySQL (tak to się pisze) nie jest żadnym sposobem komunikacji, ani przez Internet, ani przez cokolwiek innego.

Link do komentarza
Share on other sites

@mnak24 baza danych tego typu sprawdziłaby się w tym projekcie w porywach do tego, aby robot wysyłał do niej cyklicznie odczyty z czujników - miałbyś wtedy dostęp do archiwalnych danych pomiarowych. Nie ma sensu wykorzystywać jej do zdalnego sterowania pojazdu.

13 godzin temu, mnak24 napisał:

Mam też pomysł, aby użyć programów do zdalnej obsługi Rpi przez internet, tylko nie wiem czy takie rozwiązanie pozwoli mi na użycie gamepada usb do sterowania.

Możesz iść w tym kierunku pewnie da się to zrealizować. Zrobisz skrypt, który będzie sterował silnikami na podstawie np. klawiszy wciskanych na klawiaturze, a później będziesz te informacje przesyłał zdalnie przez VNC. Nadal jest to jednak mało optymalne rozwiązanie, który nie jest dedykowane do tego typu projektów. Zastanów się więc na spokojnie czy chcesz iść w tę stronę "byle zaliczyć projekt", czy jednak chcesz to zrobić porządnie. Wiem, że na studiach bywa różnie, więc nie dyskredytuję w tym kontekście żadnego z rozwiązania 😉

Link do komentarza
Share on other sites

15 godzin temu, mnak24 napisał:

Nie jestem, mysql to w zasadzie jedyny sposób komunikacji przez internet jaki nam przedstawiono.

Cześć,

proponuję trochę poczytać o protokole HTTP (tym który obsługuje serwery Stron HTML), to jest najprostszy sposób komunikacji w sieci. Oczywiście są to nadal mało optymalne metody przesyłu informacji, ale dużo prostsze niż MySQL. proponuję zacząć od np. tych linków:

https://pl.wikipedia.org/wiki/Hypertext_Transfer_Protocol

https://developer.mozilla.org/en-US/docs/Web/HTTP

jak już to przeczytasz, to zapoznaj się z protokołem RTP (jest trochę lepszy do twojego celu):

https://www.3cx.pl/voip-sip/rtp/

https://www.3cx.pl/voip-sip/rtcp/

https://en.wikipedia.org/wiki/Real-time_Transport_Protocol

Zgadzam się z kolegą @ethanak, że użycie prostej komunikacji po UDP jest w twoim przypadku prostsze.

Pozdrawiam

  • Lubię! 1
Link do komentarza
Share on other sites

Dziękuję wszystkim za odpowiedzi i naprowadzenie mnie na UDP. Znalazłem w sieci gotowy nadajnik/odbiornik w sieci LAN (link), czyli PC połączę z malinką za pomocą hamachi.

  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.