- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 10 von 10

Thema: Raspberry Roboter Websteuerung

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.05.2012
    Beiträge
    511

    Raspberry Roboter Websteuerung

    Anzeige

    E-Bike
    Hallo,
    ich möchte gerne meinen Roboter mit Raspberry-Gehirn unter anderem über eine Webseite steuern können.
    Auf dem Raspberry läuft ein lighttpd Webserver und ein Pythonscript (Steuerung der Motoren usw.).

    Die Webseite soll bei Tastendruck auf Buttons die jeweiligen Informationen ohne die Seite neu laden zu müssen an das Pythonscript weiterleiten. Aber es sollte auch möglich sein Informationen wie Sensorwerte and die Webseite zu senden (auch ohne laden der Seite).
    Das Pythonscript soll als Schleife laufen ,da es auch noch andere Schnittstellen verarbeitet.

    Wie kann ich die Kommunikation realisieren?

    Da die Webseite sich aktualisieren soll, ohne die Seite neu zu laden, muss ich da wohl etwas Javascript anwenden?

    Doch wie kann ich vom Javascript aus Informationen mit einem unabhängig laufendem Pythonprogramm austauschen?

    Meine Suche im Netz hat mir schon einige Stichworte wie ajax und cgi gebracht, doch weiß ich nicht so ganz, wie man die Kommunikation damit umsetzen kann.
    Denn bei Cgi und ajax habe ich nur Beispiele gefunden, wie diese Pythonscripte starten können. Nicht aber das, was ich gerne haben möchte.


    Würde mich freuen, wenn mir einer helfen könnte...

    Der Einsteiger

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.05.2012
    Beiträge
    511
    Nach langer Suche im Internet bin ich auf Websockets gestoßen. Das müsste doch für eine bidirektionale Schnittstelle zu einem Pythonprogramm genau das Richtige sein, oder ?

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    Ja das ist so richtig, aber dann wäre es keine Webseteuerung (über Browser) mehr ... leider entzieht sich HTML und PHP (das wäre in deinem Fall wohl die Lösung vermute ich) meinem Fähigkeitsgebiet
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    14.12.2010
    Ort
    NRW
    Beiträge
    223
    Es gibt PHP GPIO da kann man direkt mit den GPIOs kommunizieren. Dann kann man sich den Weg über Python sparen.
    cYa pig

  5. #5
    shedepe
    Gast
    Ein häufiger Weg den man bei sowas beschreitet, ist in deinem Python (oder egal welche Sprache) Programm, einen Webserver aufzumachen. Das ist in Python ca. 3 Zeilen Code. Dieser Webserver bindet sich z.B. auf Port 80 auf deiner lokalen IP Adresse. Diese kannst du dann mit deinem Browser aufmachen. Dein Browser kommuniziert mit dem Webserver über GET bzw. POST requests. Diese Request kannst du in deinem Programm selber parsen und je nach Request eine andere Aktion ausführen.

    Hört sich zwar bisschen kompliziert am Anfang an, ist aber wirklich einfach, wenn man es mal ausprobiert hat. Siehe https://docs.python.org/3/library/http.server.html


    Und noch etwas Beispielcode. Jedoch ungetestet. Habe den aus einem bestehenden Projekt ausgebaut...
    Code:
    import sys, time
    
    from http.server import BaseHTTPRequestHandler, HTTPServer
    from urllib.parse import urlparse, parse_qs
    
    class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):     
          # GET
    
          def do_GET(self):
            (host,port) = self.client_address
          
            testHTTPServer_RequestHandler.clients[host] = time.time()
            parsed = parse_qs(urlparse(self.path).query).get('text',[''])[0];
            message = "Thanks for your message!"
               
            
         
            
            # Send response status code
            self.send_response(200)
     
            # Send headers
            self.send_header('Content-type','text/html')
            self.end_headers()
     
            # Send message back to client
            #
            # Write content as utf-8 data
            self.wfile.write(bytes(message, "utf8"))
            return
    
    
    
    
    
    def main():
        print("starting server")
        server_address = ('127.0.0.1', 8080)
        httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
        httpd.timeout = 1
        while True:
            time.sleep(0.001)
            httpd.handle_request()
    
        httpd.close()
        sys.exit(app.exec_())
    
    main()

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.05.2012
    Beiträge
    511
    Danke für die Antworten

    Zu Ceos: warum ist es denn dann keine Websteuerung über Browser mehr? Wenn ich im Browser die Webseite des Pis eingebe und dann das Javascript( welches die Tcp Verbindung mit dem Server beginnt) mit einem Button starte, dann steuere ich den Roboter doch über den Browser, oder funktioniert das so nicht? Browser(TCP/Javascript) <=> Server(TCP/Python)

    Zum Thema HTML, PHP und auch GPIO:
    So wollte ich das auch erst lösen. Doch habe ich herausgefunden, dass PHP nur serverseitig ausgeführt wird. Und das schafft gleich mehrere Probleme, die ich für meine Websteuerung nicht haben möchte.

    1. Muss bei jeder Interaktion (Button click) die Webseite komplett neu geladen werden. Das habe ich früher schon mal ausprobiert. Wenn man nur einen festen Aufbau wie eine Lampe hat ist das nicht so schlimm, da diese eh nicht häufig Steuerimpulse bekommt... Da der Robi aber im WLAN ist und recht zügig Befehle empfangen muss funktioniert das nicht so toll wenn ständig die Seite neu geladen wird...

    2. Ist keine gute bidirektionale Verbindung möglich, da bei z.B. Button click man nur per PHP entweder ein Pythonscript starten könnte, was dann die Ausgabe von Steuerimpulsen erlaubt, oder man direkt per PHP wie piggituX gesagt hat die GPIOs ansteuern könnte.

    3. Möchte ich nicht die GPIOs normal nutzen, sodern möchte z.B. über I2C Motoren steuern oder Kommunikation mit anderen Dingen durchführen. Dies klappt aber nur, wenn das Script in einer Schleife laufen kann und nicht für jeden Vorgang neu gestartet werden muss...

    4. Über PHP lassen sich von einem Pythonscript keine Informationen an die Webseite schicken... (jedenfalls wenn die Bedingung 3. erfüllt sein soll)


    Das was shedepe beschreibt, hört sich doch schon mal gut an. Werde ich auf jeden Fall drüber nachdenken. Momentan habe ich das nämlich noch nicht durchblickt... Einen Nachteil sehe ich dabei aber. Es würde nicht mehr so einfach sein mehrere Webseiten mit unterschiedlichen Dingen zu basteln. Die Webseiten brauchen ja auch noch CSS und so...
    Ich möchte erst mal noch ein bisschen probieren, ob ich die TCP Lösung hinbekomme, wenn nicht, dann komme ich auf diesen Ansatz zurück.

    Der Tcp Ansatz müsste mir doch eigentlich noch einen Vorteil bringen...Theoretisch kann man doch auch die Serverseite mit dem Python Code auf einen anderen PC auslagern??

    Probiere gerade die Lösung aus: http://stackoverflow.com/questions/1...-communication

    Ich verwende gerade die Lösung Html5 socket von Antwort 1 aus dem Link für mein Javascript im Browser und für das Pythonscript(auf meinem PC, nicht auf PI!!):
    Code:
    import socketserver
    
    class ChatRequestHandler(socketserver.BaseRequestHandler):
        def handle(self):
            addr = self.client_address[0]
            print("[{}] Verbindung hergestellt".format(addr))
    
            while True:
                s = self.request.recv(1024)
                if s:
                    print("[{}] {}".format(addr, s.decode()))
                else:
                    print("[{}] Verbindung geschlossen".format(addr))
                    break
    
    server = socketserver.TCPServer(("", 50000), ChatRequestHandler)
    server.serve_forever()
    Wenn ich das Javascript von Microsoft Edge aus ausführe passiert nichts, wenn ich die Seite aber von Chrome aus verwende gibt mir mein Pythonscript das aus:

    Klicke auf die Grafik für eine größere Ansicht

Name:	socket erfolg2bearbeitet.png
Hits:	2
Größe:	31,6 KB
ID:	32518

    Leider schaffe ich es noch nicht Nachrichten zu senden oder zu empfangen...
    Wenigstens verbindet sich da was. Darauf lässt sich ja aufbauen...
    Ich verstehe nur noch nicht, wie das mit dem Handshake dings weiter unten im Link funktioniert??

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    wait what? custom websockets mit javascript im browser? okay man lernt nie aus XD
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.05.2012
    Beiträge
    511
    hab ne ganz interessante Webseite dazu gefunden: http://enterprisewebbook.com/ch8_websockets.html

    Ich muss also, bevor ich die Kommunikation beginnen kann erst mal einen Schlüssel bearbeiten und dann zurückschicken...
    Mein Programm um das zu testen sieht momentan so aus:

    Code:
    import hashlib
    import base64
    
    MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
    HSHAKE_RESP = "HTTP/1.1 101 Switching Protocols\r\n" + \
                "Upgrade: websocket\r\n" + \
                "Connection: Upgrade\r\n" + \
                "Sec-WebSocket-Accept: %s\r\n" + \
                "\r\n"
    
    data = "GET HTTP/1.1\r\n" + \
        "Upgrade: websocket\r\n" + \
        "Connection: Upgrade\r\n" + \
        "Host: echo.websocket.org\r\n" + \
        "Origin: http://www.websocket.org\r\n" + \
        "Sec-WebSocket-Key: i9ri`AfOgSsKwUlmLjIkGA==\r\n" + \
        "Sec-WebSocket-Version: 13\r\n" + \
        "Sec-WebSocket-Protocol: chat\r\n" 
    
    
    print("HSHAKE_RESP: ", HSHAKE_RESP)
    
    print("data: ", data)
    
    headers = {}
    lines = data.splitlines()
    
    for l in lines:
        parts = l.split(": ", 1)
        if len(parts) == 2:
            headers[parts[0]] = parts[1]
    headers['code'] = lines[len(lines) - 1]
    key = headers['Sec-WebSocket-Key']
    
    print("key: ", key)
    
    combi = key + MAGIC;
    
    combi_b = combi.encode('UTF-8')
    
    print("combi: ", combi)
    
    #print("combi_b: ", combi_b)
    
    resp_data = HSHAKE_RESP % ((base64.b64encode(hashlib.sha1(combi_b).digest()),))
    
    print("resp_data: ", resp_data)
    Leider bekomme ich nicht den gleichen Accept Schlüssel zum zurückschicken raus wie im Beispiel auf der Seite...
    Die schicken den Key: i9ri`AfOgSsKwUlmLjIkGA== an das Serverscript und bekommen dann, wenn sie es mit dem "special globally unique identifier (GUID) string 258EAFA5-E914-47DA-95CA-C5AB0DC85B11" bearbeitet haben das raus: Qz9Mp4/YtIjPccdpbvFEm17G8bs=

    Ich bekomme aber das raus: ti16O6oiN0nzWbVtqq9omKeAd/Y=

    warum ? Kann mir einer helfen ? Ich habe ja schließlich nichts groß verändert, sondern den Code fast von da ganz unten übernommen : http://stackoverflow.com/questions/1...ing-to-python#

  9. #9
    shedepe
    Gast
    Das was shedepe beschreibt, hört sich doch schon mal gut an. Werde ich auf jeden Fall drüber nachdenken. Momentan habe ich das nämlich noch nicht durchblickt... Einen Nachteil sehe ich dabei aber. Es würde nicht mehr so einfach sein mehrere Webseiten mit unterschiedlichen Dingen zu basteln. Die Webseiten brauchen ja auch noch CSS und so...
    Ich möchte erst mal noch ein bisschen probieren, ob ich die TCP Lösung hinbekomme, wenn nicht, dann komme ich auf diesen Ansatz zurück.
    Du kannst einen Webserver davor schalten, und nur gewissen krams weiterleiten.

    Btw:
    Meine Erfahrung mit Webseiten die Roboter steuern war in der Vergangenheit meistens von solcher Natur, dass der Roboter irgendwann an einer Wand geklebt ist, weil man einen verdammt hohen Delay haben kann.

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.05.2012
    Beiträge
    511
    Ich glaube, dass ich die Tage dann doch mal deine Lösung ausprobieren werde...
    Ich saß heute bestimmt den halben Tag daran, herauszufinden, warum auf einmal mein Javascript nicht mehr ging, obwohl ich nichts daran seit gestern gemacht hatte. Dann bin ich mal auf die Idee gekommen die Broserdaten(Cache) zu löschen und auf einmal ging es wieder... kein Plan warum ?? Dachte schon, dass mir der Raspberry einen Aprilscherz spielen wollte

    Jetzt bekomme ich schon mal wenigstens die Verbindung so hin, dass die Verbindung Clientseitig wieder angenommen wird (connection.onopen...)

    Nur das mit den Nachrichten klappt noch nicht, weil ich gerade gemerkt habe, dass nicht direkt die Daten mit xyz.encode verschickt werden, sondern die Daten in Frames transportiert werden...

    Wenn man z.B. das Wort "Pingen" mit connection.send mit dem Javascript verschickt zeigt mir Python das an: b'\x81\x860og\x80\x1f\x06\t\xe7*\x01' Wie ich das decodieren soll weiß ich noch nicht wirklich...




    Zu der Sache mit dem Delay: Ich möchte es ja wenigstens mal probieren Die meiste Zeit soll der Robi eh autonom unterwegs sein...

Ähnliche Themen

  1. Antworten: 0
    Letzter Beitrag: 15.07.2015, 21:43
  2. Gertbot: Einfacher Roboter bauen mit dem Raspberry Pi
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 18.11.2014, 12:10
  3. Raspberry pi Roboter - WLAN
    Von Probot cool im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 2
    Letzter Beitrag: 15.08.2014, 17:43
  4. Rapiro: Kleiner Roboter hat einen Raspberry Pi im Kopf
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 03.07.2013, 19:50
  5. Erster Roboter mit Raspberry Pi
    Von Zondan im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 11
    Letzter Beitrag: 17.10.2012, 12:32

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen