Projekt: Autonomer Roboter

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Kann man die Funktion auch ausführen ohne das eine Zahl in den Klammern steht oder muss ich dafür nochmal extra was deklarieren?

    Nun hör mal. Ist wirklich nicht böse gemeint, aber ich glaube, du hast nur sehr schemenhaft eine Ahnung von dem, was du tust. Jemand, der nicht einmal die Basics einer Programmiersprache kann, wird in selbiger nicht die Software für ein autonomes Fahrzeug programmieren können.

    Auch die Beiträge 28-38 und die Sache mit dem try/except zeugen davon.

    Wenn ich das lese

    Nur leider wird die Funktion in der zweiten Schleife nicht aufgerufen

    wünsche ich mir sehr, dass Anfänger (so erscheint mir dein Kenntnisstand) nicht andauernd alle möglichen Ereignisse/Fehlermeldungen gleich interpretieren. Wenn das print erfolgreich ausgeführt wurde, steht als nächstes der Aufruf der Funktion turn_left. Und ob's dir passt oder nicht, die wird aufgerufen. Ob sie das tut, was du willst und denkst, ist wieder eine andere Sache.

    Also, ich rate dir sehr, noch einmal einen Schritt zurück zu gehen und einfachere kleine Aufgaben zu lösen, um dein Wissen zu festigen.

    Auch ist es schwer zu helfen, wenn du von einem Recode und einem damit verbundenen Problem berichtest, dann etwas interpretierst und nur einen Brocken Code lieferst.

    Zu guter Letzt: wenn etwas mit dem Code nicht so klappt, hilft ein guter Debugger wie er in PyCharm eingebaut ist weiter.

    :2cents:

  • Habe es jetzt so gemacht:

    Den Timeframe=1kann man aber auch weglassen, da die Funktion turn_left()nur solange aufgerufen werden soll, bis die Distanz wieder > 15 ist.

    In meinem Code hier funktioniert es zu 50%. Der Sensor misst die Entfernung und merkt ok sie ist > 15. Sobald die Entfernung <15 ist wird einmalig die Funktion turn_left()solange ausgeführt bis die Distanz wieder >15 ist. Danach drehen sich beide Räder wieder vorwärts. Bei erneutem auslösen passiert jedoch nichts und es wird die Funktion forward()weiterhin ausgeführt auch wenn der Abstand kleiner als 15 ist obwohl zu nah ausgegeben wird.

    LG

    Bastelstube

  • timeframe=1 kannste auch drin lassen... Macht keinen Unterschied - es sei denn du hast das grundsätzlich nicht verstanden

    Wie linusg bereits sagte: Sofern "zu nah" ausgegeben wird wird auch 100% die Funktion in diesem Block ausgeführt.

    Warum es dann nicht so funktioniert wie Du erwartest liegt an was anderem... Dass stattdessen forward() ausgeführt wird obwohl "zu nah" ausgegeben wird ist eine falsche Einschätzung deinerseits.

    Aber ich wiederhole noch mal: zu viele sleeps - das wird dir früher oder später zu Verhängnis... hier ne Sekunde, plus dort noch ne Sekunde und schwups fährt dein Gefährt vor ne Wand oder fällt die Treppe runter. Last Hint.

  • Habe die sleeps jetzt mal alle rausgenommen bis auf einen (sleeptime 0.00001).

    Woran das liegt das es nicht so funktioniert wie ich erwarte überlege ich gerade. Das Gefährt soll ja erstmal geradeaus fahren und wenn der Abstand nicht mehr stimmt den turn_left() machen und wenn der Abstand wieder passt geradeaus fahren. Ich vermute, dass es an der if Anweisung liegt und nicht am else.

    LG

    Bastelstube

  • Habe die sleeps jetzt mal alle rausgenommen bis auf einen (sleeptime 0.00001).

    Auch wenn die Absicht gut gemeint ist, wird das ohne signifikanter Anpassungen des Codes nicht funktionieren ;)


    Woher weißt du denn dass turn_left() definitiv nicht ausgeführt wurde? Am einfachsten findest du es raus indem du ein print in die Funktion einfügst:


    Bitte - BITTE - probiere erst den obigen Code aus... Ich greife jetzt mal voraus und hoffe das du hierzu nicht zu viele Fragen stellst sondern erst selber versuchst den Code zu verstehen

    Spoiler anzeigen

    selbstverständlich ginge es noch weit aus eleganter - aber eins nachm anderen.

  • wünsche ich mir sehr, dass Anfänger (so erscheint mir dein Kenntnisstand) nicht andauernd alle möglichen Ereignisse/Fehlermeldungen gleich interpretieren. Wenn das print erfolgreich ausgeführt wurde, steht als nächstes der Aufruf der Funktion turn_left. Und ob's dir passt oder nicht, die wird aufgerufen. Ob sie das tut, was du willst und denkst, ist wieder eine andere Sache.


    Also, ich rate dir sehr, noch einmal einen Schritt zurück zu gehen und einfachere kleine Aufgaben zu lösen, um dein Wissen zu festigen.


    Auch ist es schwer zu helfen, wenn du von einem Recode und einem damit verbundenen Problem berichtest, dann etwas interpretierst und nur einen Brocken Code lieferst.

    Das das print erfolgreich aufgerufen wird ist mir klar und das die Funktion turn_left() aufgerufen wird auch und das Sie momentan nicht das macht was Sie soll. Es geht ja darum, dass ich gefragt habe ob man mir helfen kann bzgl. dessen und ich mich bevor ich was frage informiere. Ich habe nun mehrere Möglichkeiten ausprobiert und mir einiges dazu durchgelesen doch ich komme nicht weiter. Aus diesem Grund wende ich mich ja an das Forum hier um eine Antwort auf mein Problem zu bekommen. Ich will keinen fertigen Code oder sonst was, aber ein Beispiel von jemanden der wirklich weis wie es funktioniert würde mir da schon um einiges weiterhelfen und man müsste hier nicht dauerhaft Post für Post reinstellen und das Forum voll spamen. :)

    LG

    Bastelstube

  • Ich habe nun mehrere Möglichkeiten ausprobiert

    auch wenn sich meine Antwort nun böse anhört,

    was du anscheinend noch nicht probiert hast ist programmieren lernen.

    Programmieren ist nicht Versuch und Irrtum, Programmieren ist nach Konzept arbeiten, den berühmten Kuchen backen!

    Raspberry Pi zur Spannungsüberwachung einsetzen, aber wie und ist es möglich?

    lasst die PIs & ESPs am Leben !
    Energiesparen:
    Das Gehirn kann in Standby gehen. Abschalten spart aber noch mehr Energie, was immer mehr nutzen. Dieter Nuhr
    (ich kann leider nicht schneller fahren, vor mir fährt ein GTi)

  • Der Tipp programmieren lernen ist meckern? (oder gings nur mal wieder ums Contra? )

    lasst die PIs & ESPs am Leben !
    Energiesparen:
    Das Gehirn kann in Standby gehen. Abschalten spart aber noch mehr Energie, was immer mehr nutzen. Dieter Nuhr
    (ich kann leider nicht schneller fahren, vor mir fährt ein GTi)

  • dann fange bei dir an bevor du meckern schreibst!

    lasst die PIs & ESPs am Leben !
    Energiesparen:
    Das Gehirn kann in Standby gehen. Abschalten spart aber noch mehr Energie, was immer mehr nutzen. Dieter Nuhr
    (ich kann leider nicht schneller fahren, vor mir fährt ein GTi)

  • Woher weißt du denn dass turn_left() definitiv nicht ausgeführt wurde? Am einfachsten findest du es raus indem du ein print in die Funktion einfügst:

    Nach dem einfügen deines Codes, erhalte ich folgende Ausgabe (Siehe Spoiler).

    Ausgabe:

    Spoiler anzeigen

    Cpi@raspberrypi:~ $ pi@raspberrypi:~ $ sudo python MotorTest.py

    Entfernung = 166.63 cm

    forward

    Entfernung = 166.27 cm

    forward

    Entfernung = 3.58 cm

    zu nah

    turn_left

    Entfernung = 3.50 cm

    zu nah

    turn_left

    Entfernung = 3.72 cm

    zu nah

    turn_left

    Entfernung = 16.89 cm

    forward

    Entfernung = 23.07 cm

    forward

    Entfernung = 166.72 cm

    forward

    Entfernung = 167.21 cm

    forward

    Entfernung = 166.29 cm

    forward

    Entfernung = 7.97 cm

    zu nah

    turn_left

    Entfernung = 8.37 cm

    zu nah

    turn_left

    Entfernung = 166.29 cm

    forward

    ^Cpi@raspberrypi:~ $


    Die Funktion forward()und turn_left()wird anscheinend ausgeführt, nur nicht mit dem gewünschten Erfolg. Hierbei ging es aber ja aktuell um die Frage ob die Funktionen überhaupt ausgeführt werden und dem ist so.

    Den Code den du als zweites gepostet hast habe ich mal versucht zu analysieren:

    Spoiler anzeigen

    import multiprocessing as mp = Kürzen von multiprocessingin mp

    from threading import Thread = Von Threadingimportierst Du nur Thread

    Funktion(telemetry)= Du setzt mit telemetryeine Variabel in die Funktion

    telemetry["steer to"] = stop= Du schreibst["steer to"]in ein Array und sagst damit, wenn telemtry["steer to"] = stopaufgerufen wird, dann soll das Gefährt stoppen. ["steer to"]heißt in dem Fall sowas wie "Fahre zu".

    print("Steering: {}".format(telemtry["steer to"]))= Hier sagst Du "Lenke/Fahre: Ausgabe des Array" Formatierung(Übergabe des Namens der Funktion["Angabe des Arrays"]



    def measure_distance(telemetry, status):=Du übergibst der Funktion die Variabeln telemtry und status

    while status["running"]: = Solange der Status bzw. das Array ["running"]ausgeführt wird.

    if status["stop"]: = Wenn der Status bzw. das Array ["stop"] ausgeführt wird, mache nichts und warte auf Eingabe.

    telemetry["distance"] = time_elapsed / 0.000058 = Du nimmst das Array ["distance"] und übergibst Ihm den Wert time_elapsed / 0.000058


    if (int(time.time()) - start_time) >= status["distance_announce_time"]: = Du sagst das time.time als int deklariert sein soll. Wenn status[distance_announce_time"]:kleiner oder gleich als if (int(time.time()) - start_time), dann print("Distanz: {}".format(telemetry["distance"])). Heißt dann gebe den Wert aus ["distance"] mit (Distanz: )wieder.

    status = mp.Manager().dict()= Du deklarierst jeweil für statusund telemtryeinen eigenen Prozess auf dem Prozessor.

    status["running"]=True = Wenn das Array ["running"]=1/Wahr ist dann

    status["distance_announce_time"] = Zeit zwischen den Messungen des Sensors

    measure_t = Thread(target=measure_distance, args=(telemetry, status,)) = Hier bin ich mir nicht ganz sicher was passiert. Ich vermute das in measure_t die einzelnen Prozesse geschrieben werden.

    measure_t.start() = Führe die Variabel measure_t aus.

    status["running"]=False = Beende das Programm bzw. warte auf Eingabe

    LG

    Bastelstube

  • Die Funktion forward()und turn_left()wird anscheinend ausgeführt, nur nicht mit dem gewünschten Erfolg. Hierbei ging es aber ja aktuell um die Frage ob die Funktionen überhaupt ausgeführt werden und dem ist so.

    Dann liegt das an deiner Hardware, denn die Software macht das was programmiert wurde - prüf deine Verkabelung.

    Den Code den du als zweites gepostet hast habe ich mal versucht zu analysieren:

    Deine Analyse ist nicht ganz so toll, aber schön das du es zumindest versucht hast ;)

    In Python Hier gibt es keine Arrays, das was du damit meinst ist ein Dictionary. In telemetry sind keine Ausführungen enthalten sondern nur (Bewegungs)Informationen.

    Für telemetry["steerTo"] = "stop" ist bisher nichts programmiert, nur für status["stop"] = Truedh wenn "stop" auf True gestellt wird führt das noch längst nicht dazu dass irgendwas stoppt. Dafür ist bisher nur in measure_distance() eine Vorgehensweise eingebaut: Messung aussetzen.

    telemtry["steer to"] ist zudem falsch, es heißt telemtry["steerTo"] ... Und es ist wie gesagt keine Funktion.

    Wie du darauf kommst dass für status und telemetry ein eigener Prozess erstellt wird ist mir schleierhaft. Was da durch mp gemacht wird ist extra kommentiert. mp bzw multiprocessing ist zwar das was der Name verrät, aber das Module ist nicht nur "multi processing" sondern sehr mächtig und ich nutze hier nur einen bestimmten Teil.

    status["distance_announce_time"] ist kein "Zeit zwischen den Messungen". Announce bedeutet sowas wie Ausgabe / Bekannt geben. Dh es werden alle 0.5 Sekunden eine Messung durchgeführt aber nur alle 2 Sekunden der aktuelle Wert ausgegeben.

    time.time() gibt normalerweise einen Float-Wert des sog. Unix-Timestamp aus. Durch int(time.time()) mach ich das zu einer Ganzzahl weil der Float nicht benötigt wird.

    ...den Rest kommentier ich jetzt nicht da leider größtenteils durch vorherige Fehlinterpretationen Quatsch oder eher irrelevant...

    telemetry sollte möglichst immer aktuelle (Bewegungs)Informationen enthalten.

    measure_distance() wird in einem separaten Thread vom Rest abgekoppelt ausgeführt und durchläuft alle 0.5 Sekunden einen neuen Messvorgang.

    telemetry und status muss ein "shared dictionary" sein damit die sog. Inter-Process-Communikation funktioniert und von anderen Threads/Prozessen veränderbar sind. In diesem Fall ein separater Thread, was zu diesem Zeitpunkt ausreicht.. Nur wenn es noch etliche andere Auslagerungen benötigen würde, sollte man statt zusätzlicher Threads lieber zu Sub-Prozessen greifen, da performanter.

    Die eigentliche Logik bzw Programmablauf wird in der while der main() Funktion verarbeitet.

  • Das ist aber alles sehr schwammig und ungenau/fachlich nicht korrekt.

    import multiprocessing as mp = Kürzen von multiprocessingin mp

    Importieren des Packages multiprocessing in den globalen Namespace unter dem Namen mp

    from threading import Thread = Von Threadingimportierst Du nur Thread

    Fast - Groß/Kleinschreibung beachten ;)

    Funktion(telemetry)= Du setzt mit telemetryeine Variabel in die Funktion

    Wo kommt das vor? Ich find's gerade nicht...

    Wennschon: Du übergibst Funktion (sei das jetzt eine Klasse oder Funktion, wäre dann aber schlecht benannt) die Variable telemetry als Argument

    telemetry["steer to"] = stop= Du schreibst["steer to"]in ein Array und sagst damit, wenn telemtry["steer to"] = stopaufgerufen wird, dann soll das Gefährt stoppen. ["steer to"]heißt in dem Fall sowas wie "Fahre zu".

    Das ist kein Array, sondern ein dict. Entscheidender Unterschied. Keine Indizierung über Indizes möglich, sondern Key/Value Zuordnung. Was meinst du mit "wenn telemtry["steer to"] = stopaufgerufen wird"? Das ist eine Zuweisung...

    def measure_distance(telemetry, status):=Du übergibst der Funktion die Variabeln telemtry und status

    Nö. Es wird eine Funktion measure_distance mit den Parametern telemetry und status definiert. Nix aufgerufen oder übergeben.

    while status["running"]: = Solange der Status bzw. das Array ["running"]ausgeführt wird.

    ?

    Solange bool(status["running"]) True ergibt...

    if status["stop"]: = Wenn der Status bzw. das Array ["stop"] ausgeführt wird, mache nichts und warte auf Eingabe.

    Wieso immer ausgeführt? Selbes wie oben, bool...

    telemetry["distance"] = time_elapsed / 0.000058 = Du nimmst das Array ["distance"] und übergibst Ihm den Wert time_elapsed / 0.000058

    Dict. Es wird dem Key "distance" im dict telemetry der Wert time_elapsed / 0.000058 zugewiesen.

    if (int(time.time()) - start_time) >= status["distance_announce_time"]: = Du sagst das time.time als int deklariert sein soll. Wenn status[distance_announce_time"]:kleiner oder gleich als if (int(time.time()) - start_time), dann print("Distanz: {}".format(telemetry["distance"])). Heißt dann gebe den Wert aus ["distance"] mit (Distanz: )wieder.

    Nicht deklariert, umgewandelt. time.time() gibt einen float zurück. Der Rest passt :thumbup:

    status = mp.Manager().dict()= Du deklarierst jeweil für statusund telemtryeinen eigenen Prozess auf dem Prozessor.

    ?

    Nein, es werden zwei leere dicts erstellt und den Variablen status und telemetry zugewiesen... Allerdings braucht's hier IPC, deshalb kein dict() oder {} sondern über multiprocessing.Manager.

    status["running"]=True = Wenn das Array ["running"]=1/Wahr ist dann

    Dict und Zuweisung...

    measure_t = Thread(target=measure_distance, args=(telemetry, status,)) = Hier bin ich mir nicht ganz sicher was passiert. Ich vermute das in measure_t die einzelnen Prozesse geschrieben werden.

    Es wird eine Instanz von Thread erstellt, der die Funktion measure_distance mit den Argumenten telemetry und status in einem neuen Thread starten soll.

    measure_t.start() = Führe die Variabel measure_t aus.

    Ruft die Methode start von der Instanz von Thread auf, ergo wird der Thread gestartet.

  • Dann liegt das an deiner Hardware, denn die Software macht das was programmiert wurde - prüf deine Verkabelung.

    Also ich gehe in zwei Varianten vor.

    Bei der ersten starte ich das Gefährt, lasse es ein paar Sekunden geradeaus fahren und halte dann meine Hand vor den Sensor. Eine Ausgabe mit der Ditanz und das es zu nah ist erfolgt, jedoch macht er nicht den gewünschten turn_left().

    Bei der zweiten Variante halte ich eine Hand vor dem Starten schon vor den Sensor. Anschließend starte ich das Programm, während meine Hand noch über dem Sensor ist. Das gefährt fährt kurz vorwärts, erkennt dann das die Distanz < 15 ist und macht den gewünschten turn_left() für die zwei Sekunden und fährt danach wieder geradeaus. Wenn ich jedoch erneut die Hand vorhalte passiert genau das wie bei der ersten Variante.

    Es ist ja so programmiert, dass er immer wieder den turn_left()für zwei Sekunden machen soll, sobald die Distanz < 15 ist. Es sei denn das Programm wird abgebrochen.

    Bin gerade nochmal die Verkabelung durchgegangen es scheint alles in Orndung zu sein. Habe dies auch nochmal in Fritzing mit meinem Verkabelungsplan abgeglichen.


    Ich bin dir und linusg sehr dankbar, dass Ihr den anderen Quellcode mir nochmal aufgeschlüsselt habt. Ich werde die Aussagen von euch verfolgen und lernen Sie komplett zu verstehen. :)

    LG

    Bastelstube

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!