Servo-Pendelbewegung mit class

  • Hallo,

    bin am Umstellen meines kleinen Roboters von C++ auf Python und will dabei auch Python lernen. In C++ habe ich alles prozedural programmiert mit 80% globaler Variablen :blush:.

    Zuerst möchte ich an folgender Umstellung lernen:

    Ein Servo trägt einen US-Sensor und pendelt von li nach re und wieder zurück (6, 14, 18, 22, 26, 22, 18, 14, 6, 14....) und misst dann zu jeder Winkelposition ob ein Hindernis vorliegt. Das ging vorher prozedural und soll jetzt ohne globale Variablen und Listen per Klasse programmiert werden . Wie könnte so eine Klasse aussehen die den Servo initialisiert (PWM, Richtung...) und dann von unterschiedlichen Funktionen weitergetaktet oder abgefragt werden kann?

    In Klasse: initalisierung Servo, PWM, Pin / Liste mit Winkeln / aktuelle Winkelposition / aktuelle Bewegungsrichtung ….

    Irgendwann sollte das pendeln des Servos und abfragen der Entfernung pro Winkel in einem eigenen Prozess laufen und nicht von anderen Programmstellen (wenn mal Zeit ist) weitergetaktet werden. Habe aber nur ein Zero im Einsatz der nur einen Prozess machen kann und das Thema Prozesse möchte ich jetzt erst mal schieben sonst wird mir das zu viel. Unter C++ habe ich das mit Zeitabfragen gemacht und nach 300ms war dann der Servo für die nächste Bewegung dran. Will ich das für den Anfang auch unter Python machen - da kann Vieles aus c++ übernommen werden.

    Ich hoffe ich konnte meine Frage verständlich beschreiben!

    Danke

  • Hallo,

    also grundsätzlich _musst_ du keine Klasse in Python schreiben. Python ist nicht Java, wo alles in eine Klasse muss.

    Wenn du das in eine Klasse packst, sähe das Gerüst vielleicht so aus:

    Python
    class MoveAndMeasure:
        def __init__(self):
            self.pin = 17
            #was auch immer noch an Attributen sinnvoll ist
        def move_servo(self):
            #Code zum Bewegen des Servors
        def measure_distance(self):
            #Code zum Messen der Distanz
            return distance

    Die Methoden `move_servo` und `measure_distance` muss du trotzdem periodisch aufrufen, dass passiert nicht automagisch.

    Wenn das ganze später aber sowie so in einem Prozess (oder Thread) laufen soll, dann kannst du das auch ohne Klasse in eine `while=True` Endlosschleife packen und das Ergebnis der Distanzmessung über eine Queue mit dem anderen Prozess / Thread teilen.

    Gruß, noisefloor

  • Ich wuerde vor allem erstmal in Frage stellen, warum es Python sein soll. Gerade auf dem so kleinen und langsamen Zero wird das die Leistung des Systems negativ beeinflussen. Ich bin ja ein grosser Freund von Python, aber meinen Roboter programmiere ich gerade in Rust, oder C++.

  • Ich wuerde vor allem erstmal in Frage stellen, warum es Python sein soll. Gerade auf dem so kleinen und langsamen Zero wird das die Leistung des Systems negativ beeinflussen. Ich bin ja ein grosser Freund von Python, aber meinen Roboter programmiere ich gerade in Rust, oder C++.

    Ja, aber es gehen die Bibliotheken aus. Wiring.Pi hört auf und BCM2835 ist auch recht inaktiv, oder sehe ich das falsch?

    Ich wuerde vor allem erstmal in Frage stellen, warum es Python sein soll. Gerade auf dem so kleinen und langsamen Zero wird das die Leistung des Systems negativ beeinflussen. Ich bin ja ein grosser Freund von Python, aber meinen Roboter programmiere ich gerade in Rust, oder C++.

    Ja stimmt, habe noch einen 3B+ übrig den ich dann als nächstes wohl auch einbauen werde.


    Danke ich schau mir das mal an.

  • wiringPI ist eine Trotzreaktion von Gordon. Die BCM2835 updated sich wenn noetig (PI4 zB). Und dann gibt es die von mir bevorzugte pigpio, und die wird aktiv entwickelt (selbst gerade einen PR auf github besprochen, und ist gemerged worden). Aber ganz ehrlich: das Thema ist auch nur so lange beackerbar. Die Hardware aendert sich nicht oft, was soll da bei den Bibliotheken passieren?


    Und Python baut auf die genannten Bibliotheken auf (zumindest teilweise, zB pigpio bei gpiozero wenn man will (und man sollte wollen))

  • wiringPI ist eine Trotzreaktion von Gordon. Die BCM2835 updated sich wenn noetig (PI4 zB). Und dann gibt es die von mir bevorzugte pigpio, und die wird aktiv entwickelt (selbst gerade einen PR auf github besprochen, und ist gemerged worden). Aber ganz ehrlich: das Thema ist auch nur so lange beackerbar. Die Hardware aendert sich nicht oft, was soll da bei den Bibliotheken passieren?


    Und Python baut auf die genannten Bibliotheken auf (zumindest teilweise, zB pigpio bei gpiozero wenn man will (und man sollte wollen))

    Das wusste ich nicht, dass das pigpio auch für C++ geht - schaue ich mir an. Komme mit C++ aber beim Raspi nicht so schnell vorwärts wie mit Python. Brauche die Sprache auch für meine kaufmännischen Angelegenheiten und da bin ich mit Python universeller, auch mit Eingabeformularen u.s.w.

  • Das man mit Python schneller programmiert ist unbestritten. Ob die Ergebnisse dann ausreichend sind, wenn es um Performance und Wiederholgenauigkeit geht, steht auf einem anderen Blatt. Gerade die niederen Funktionen eines Roboters sind eher eine Sache fuer deterministische, schnelle Sprachen. Und dann hoehere Dinge wie Wegeplanung, Kartenbildung etc etwas fuer Python. Aber da kommt es natuerlich auch auf den Anspruch an.

  • Die 10 mal an sich sind kein Problem, aber Python ist keine deterministische Sprache. C++ *kann* eine deterministische Sprache sein. Soll heissen: die Ausfuehrung erfordert keine Anforderung von Systemresourcen, wenn man aufpasst. Und dadurch wird das Programm nicht unvorhersehbar lang gestoppt.

  • Glaube nicht, dass meine Anforderungen zu hoch sind für Python. Da ist noch viel Luft meinerseits als Dummy-Python-Programmierer:D . Erstmal werde ich mit dem Servo und der Entfernungsmessung "spielen" dann kommt das Monster-Motorshield dran mit der Mortorsteuerung und dann kann ich die Sache abschätzen ob irgend etwas hängen bleibt. Alles andere wie Sound, Stromfühler und Bluetooth, was ich jetzt noch drin habe, sind nicht zeitkritisch. Zur Not kann man ja vielleicht zeitkritische Dinge in C realisieren.

  • Hallo,

    würde mich freuen wenn jemand einmal "Fehler lesen" könnte.

    Vielen Dank!

  • Ein netter Anfang, aber noch sehr viel zu verbessern.

    Du erzeugst das pi-Objekt in der Klasse. Das ist ein Fehler, das muss als argument reingereicht werden. Du setzt die Servo position zweimal. Einmal reicht. Die Berechnung von spos ist umständlich, für solche Fälle benutzt man den Modul-Operator %. Das das Servo den ganzen pi stoppt ist auch falsch. Stattdessen muss das aufhören sich zu bewegen. Das kann zb durch eine Flagge geschehen, die ihren wahrheitswert wechselt.

    Die ganz große Thematik aber ist dein Umgang mit Zeit. Das es time.sleep gibt, solltest du sofort vergessen. Du wirst nichts außer Kleinkram hinbekommen, wenn du jede Komponente so schreibst, als ob die die Kontrolle über die Zeit hätte. Denn dann kannst du immer nur eine Sache auf einmal machen. Das geht aber bei einem Roboter nicht. In den 3 Sekunden fährt der gegen die Wand.

    Für so eines wie dein Problem braucht es eine zentrale Schleife, die einer ganzen Reihe von Objekten reihum durch aufruf zb einer update -Methode die Möglichkeit gibt, etwas zu tun. Oder auch nicht. Und dadurch modellierst du den Verlauf der Zeit.

  • Hallo

    Ja, das mit der übergeordneten zentralen Zeitschleife ist mir klar. In meinem C++ -Programm habe ich das natürlich drin und führe, je nach Dringlichkeit der Komponenten, z.b. alle 200ms A aus und alle 1000ms Komponente B u.s.w.

    Im Programm oben geht es mir aber nur um Übung und Verständnis von Python-Basics, Python-Klassen und wie Komponenen mit pigpio anstatt WiringPi angesteuert werden. Ich muss Schritt für Schritt vorgehen.

    Ich werde dann mal deine Anpassungshinweise zu obigem Programm angehen.

  • Es ist ein bisschen schwer, etwas zu reviewen, wenn das Ziel nicht das ist, was man denkt das es ist. Ich kann dir kein Feedback geben, wenn es im Grunde nur darum geht, irgendwas irgendwie mit Python zu machen. Denn dann kommt zu jeder Anmerkung nur "weiss ich, aber HIER will ich das ja bewusst anders machen". Was soll dabei rumkommen? Wenn dein Code so funktioniert, wie er gerade funktionieren soll - gut. Dann ist doch alles richtig.

  • Ich müsste dann hier mein ganzes Programm vorstellen (Zeitschlitzsteuerung, Servo, US-Entfernungsmesser, Motorsteuerung mit Ausweichmanövern bei Hindernis u.s.w ) um dann festzustellen daß ich schon bei den grundlegensten Dingen falsch vorgegangen bin wie z.B.....

    Zitat

    Du erzeugst das pi-Objekt in der Klasse. Das ist ein Fehler, das muss als argument reingereicht werden

    Diese Info hilft mir und ich kann so eine Komponente nach der anderen sauber in Betrieb nehmen und dann später als Programm mit übergeordneter Schleife zusammenfügen. Was ist an dieser Vorgehensweise nicht ok?

  • Das es ein Satz aus 20 war, den ich geschrieben habe, und es frustrierend ist, das die zwingend notwendigen Veraenderungen abgebuegelt werden mit "jaja, weiss ich ja, aber mache ich nicht". Darauf hat man dann keine Lust.

    Wenn du weisst, dass du eine Zeitscheinebsteuerung brauchst, und das Servo der untergeordnet ist, dann schreib die doch zuerst. Wenn du dann neben dem Servo den US-Sensor in Betrieb nehmen willst, faellt dir selbst auf, dass sowohl das Servo als auch der US dieses pi-Objekt benoetigen. Wenn dir dann nicht klar ist, wie du das am besten umsetzt, ist das eine deutlich spezifischere und anhand des gesamten Programmes auch sinnvoller zu beantwortende Frage.

  • Zitat


    dass sowohl das Servo als auch der US dieses pi-Objekt benoetigen

    und die Motoren dann auch. Oh das alles auf einmal zu schreiben macht sicher Sinn überfordert mich aber. Weis nicht mal was mit PWM-Soft und was mit PWM-Hardware (WiringPi) laufen kann/muss. Wenn ich dann schon einen Berg gecodet habe ….

    Ich schau mir jetzt doch erstmal den Servo an und werde dann sicher einiges wieder verwerfen müssen - da gebe ich dir recht.

  • Ich habe ja nicht gesagt, das du alles in einem Rutsch machen sollst. Aber das zentrale Element Zeitscheibensteuerung bestimmt nunmal, wie die *anderen* Dinge gecodet werden muessen. Auch wenn es erstmal nur das Servo, und dann der USS zum Servo ist.

Jetzt mitmachen!

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