Zeitfunktion

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
RCLK
User
Beiträge: 15
Registriert: Donnerstag 17. Oktober 2019, 10:10

Hallo zusammen,

ich habe ein problem mit der Zeitfunktion. Ich habe bei meinem Programm ein Zähler eingebaut. Nun will ich aber das dieser Zähler nach einer bestimmten zeit wieder auf 0 gesetzt wird. Ich habe schon lange gesucht und leider nichts hilfreiches gefunden. Ich möchte nicht das die ganze funktion stillgelegt wird. Ich möchte nur den Zähler nach beispielsweise 10 sekunden wieder auf 0 setzten.

Ich würd mich sehr freuen wenn ihr mir dabei weiterhelfen könntet einen Ansatzt zu finden.

Danke schonmal und Lg.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Aus der Beschreibung werde ich nicht schlau. Was meinst Du mit "Zeitfunktion" Wo wird welcher Zähler wie gezählt und was meinst Du mit „stillgelegt”?

Ganz allgemein macht man das mit einer if-Abfrage:

Code: Alles auswählen

if zaehler > 10:
    zaehler = 0
RCLK
User
Beiträge: 15
Registriert: Donnerstag 17. Oktober 2019, 10:10

Also ich habe folgende If abfrage:

Code: Alles auswählen

if counter == 0 and (len(stop) > 0 or WhitePixels > 4000):
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(processed_frame, 'STOP', (500, 60), font, 0.8, (255,0,0), 2, cv2.CV_AA)
            motor.setSpeed(0)
            time.sleep(3)
            motor.setSpeed(speed)
            motor.forward()
            counter +=3
            print (counter)
         
if counter >=1 and (len(stop) >0 or WhitePixels >4000):
            motor.setSpeed(speed)
            motor.forward()
            car_dir.turn(steering_angle_PWM)
            counter -=1
            print (counter)
Nach der ersten If-Abfrage soll der counter nach ungefähr 10 sekunden wieder auf 0 gesetzt werden. Mit Zeitfunktionen meinte ich, ob es in der Bibliothek "time" eine Funktion gibt die mir bei diesem Problem helfen könnte.
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Code: Alles auswählen

import time

time.sleep(10)
counter = 0
Macht was du beschrieben hast. Das ist aber wahrscheinlich nicht das nachdem du gesucht hast. Es würde helfen wenn du einmal dein ganzes Vorhaben schilderst. (Was willst du machen? Wie? Und warum?)
Zuletzt geändert von Jankie am Montag 6. Januar 2020, 15:39, insgesamt 1-mal geändert.
RCLK
User
Beiträge: 15
Registriert: Donnerstag 17. Oktober 2019, 10:10

Hab vergessen zu erwähnen das diese if-Abfrage innerhalb einer for-schleife durchlaufen wird. Das heißt mit time.sleep würde die gesamte for schleife für 10 sekunden stoppen. Ich möcte aber das das Programm weiterläuft. Ich weis das es mit threads gehen würde, nur weis ich nicht wie das in python funktioniert.

Mein vorhaben ist folgendes:
Ich habe ein selbstfahrendes Auto mit dem Raspbarry pi 3 zusammengebastelt und programmiert. Nun habe ich ein Stoppschilderkennung und die Erkennung eines Zebrastreifens integriert. Nun will ich das das auto vor dem zebrastreifen und dem Stoppschild für 3 sekunden anhält und dann weiterfährt. Das Problem ist nur das das Auto mehr als einamal vor Stoppschild und co. anhlt. Deswegen der counter. Aber da ich nicht weiß wie hoch ich den Counter ansetzen muss, will ich den nach 10 sekunden wieder auf 0 setzten. Ich hoffe ich konnte das jetzt gut veranschaulichen.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Lass die Finger von Threads. Das macht die Sache nur komplizierter.

Die Loesung ist ganz einfach: du brauchst eine kleine Zustandsmaschine, die den Zustand des Systems beschreibt. Also zB fahrend, gestoppt. Und wenn du deinen Zebrastreifen oder das Stoppschild siehst, dann wechselt der Zustand von fahrend nach gestoppt. In der zentralen Schleife (while, nicht for) wird nun je nach Zustand was unterschiedliches gemacht. Wenn du in "fahrend" bist, machst du deine Bilderkennung. Wenn du "gestoppt" bist, dann machst du was auch immer du sonst so machen musst/willst, vor allem aber pruefst du, ob genug Zeit verstrichen ist. Eine grobe Skizze:

Code: Alles auswählen

state = "fahrend"
timeout = time.monotonic()
while True:
     ... # etwas das immer vorher passiert
    if state == "fahrend":
        if ich_sehe_ein_stoppschild():
            state = "gestoppt"
            timeout = time.monotonic() + WARTEZEIT # zB 3 sekunden
    elif state == "gestoppt":
        if time.monotonic() >= timeout:
            state = "fahrend"
RCLK
User
Beiträge: 15
Registriert: Donnerstag 17. Oktober 2019, 10:10

Danke schonmal für die Hilfe, ich habe es jetzt so geschrieben wo ich denke das es klappen wird. Leider weis mein raspbarry nicht was time.monotonic ist obwohl die time Bibliothek installiert ist. time.sleep habe ich schon öfter verwendet. Woran kann das liegen?
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann verwendest du noch Python 2 - etwas, das du nicht mehr tun solltest, vor allem nicht mehr in diesem Jahr. Ab Python 3 ist das bekannt.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Noch ein Nachtrag: in Python 2 kannst du time.time stattdessen verwenden, allerdings ist das potentiell problematisch weil es zB bei einer Schaltsekunde etc. nicht funktioniert. Und Python 2 ist wirklich nichts, worin man mehr arbeiten sollte.
RCLK
User
Beiträge: 15
Registriert: Donnerstag 17. Oktober 2019, 10:10

Leider sind alle meine Pakete bis jetzt nur für python 2.7 installiert worden. Zum beispiel Opencv. Wie kann ich nun opencv für python 3 installieren?
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nicht anders als fuer python 2.7. Entweder aus dem Paketmanager, oder per selbst-bauen, fuer beides gibt es Anleitungen.
RCLK
User
Beiträge: 15
Registriert: Donnerstag 17. Oktober 2019, 10:10

Ich versuche das mal für python3 zu installieren. Dabei weis ich das ich schonfür python2 ziemlich lange gebraucht habe. Trotzdem danke für die Hilfe, hast mir sehr weitergeholfen.
RCLK
User
Beiträge: 15
Registriert: Donnerstag 17. Oktober 2019, 10:10

Das mit time.time funktioniert, aber egal um wie viel ich timeout steiger er bleibt immer nur ganz kurz stehen und fährt weiter. Wie kann ich dafür sorgen, dass er genau 3 sekunden anhält?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Was soll man dazu ohne den Code sagen?
RCLK
User
Beiträge: 15
Registriert: Donnerstag 17. Oktober 2019, 10:10

Mein code sieht folgendermaßen aus:

Code: Alles auswählen

state == "driving":
motor.setSpeed(speed)
motor.forward()
car_dir.turn(steering_angle_PWM)
steer_procent = offset / 2

if WhitePixels > 4000 or len(stop) >= 1: 
    state = "stopp"
    timeout = time.time() + 3
elif state == "stopp":
    while timeout <= time.time():
        motor.setSpeed(0)
        
    state = "driving"
    
Egal wie sehr ich den Paramete timeout änder, das Auto stoppt immer nur ganz kurz und fährt dann weiter. Was mache ich hier falsch?
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@RCLK: Also erst einmal sollte `state` und der Motor sich nicht widersprechen. Wenn Du `state` auf "stopp" setzt, dann sollte auch tatsächlich der Motor gestoppt werden.

Und dann ist da die ``whule``-Schleife im "stopp"-Zustand die da nicht hin gehört. Die würde doch wieder blockieren. Und es macht ja auch keinen Sinn die Motorgeschwindigkeit immer und immer wieder auf 0 zu setzen.

Der Code ist so doch auch gar nicht das was läuft, denn schon die erste Zeile ist syntaktisch falsch. Die kommt so nicht einmal am Compiler vorbei.

Die Namen sollten überarbeitet werden. `WhitePixels` ist der Name einer Klasse. Wenn das keine Klasse ist, sollte es `white_pixels` heissen. Oder vielleicht auch besser `white_pixel_count`. `stop` ist ein komischer Name für etwas das eine Länge hat. Was ist das? Was ist `procent`? Kann es sein dass das `percent` heissen sollte? `timeout` ist IMHO kein guter Name für einen Zeitpunkt, weil Zeitüberschreitungen in der Regel als Zeitdauer angegeben werden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Und wie sieht die Schleife drumherum aus? Wie wird garantiert, dass Du nicht immer im ersten if landest?
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die *EINE* while-Schleife aus meinem Beispiel ist die einzige, die du haben darfst. Dann funktioniert das auch mit dem stoppen/weiterfahren. Der Wechsel von driving zu stopp muss *in dem Moment* die Motoren ausschalten. Im elif zum "stopp" wird dann nur geprueft, ob die Zeit verflossen ist - also "if timeout <= time.time()" - und wenn das der Fall ist, dann Zustand wieder auf "driving", und Motorn an.

Im if zu driving musst du dann eben deine Ergebnisse der Bilderkennund auswerten etc.
Antworten