Eigenbau / Scratch Build RoπLawnMow

Sieht gut aus !
Für die Ebene auf jeden Fall eine brauchbare Lösung. Ich vermute, die Zackenräder an der Hinterachse brauchst du für die nötige Traktion, damit der Rover vorn dreht. Hier würde das Mecanum Wheel wahrscheinlich mit zusätzlichem, seitlichen Moment noch etwas zum Wendemanöver beitragen. Das zusätzliche Gewicht von deinem Aufbau wird diesbezüglich auch noch einmal interessant. Das kann helfen durch mehr Andruck, aber auch schaden - das wird man sehen.
Bei mir ist leider der alte/leise 3D-Drucker ausgefallen, mit dem ich die TPU-Räder drucken wollte. Ich habe 3 Varianten bisher probiert, alle 3 sind leider nicht zielführend - ich werde berichten.
Die letzten Tage habe ich die Navigation von 5Hz auf 10Hz erhöht und noch versucht Quantifizierungs-„Fehler“ zu bereinigen - also Integer raus und durch Float ersetzen um möglichst geschmeidige Regelung zu bekommen - Feldtest steht aus.
Na dann bin ich mal gespannt auf dein Gesamtergebnis.
Vielleicht wird man dich ja zum Ritter des Allradmähens schlagen - warten wirs ab.
Gruß Fürst Ruprecht
 
Sieht gut aus !
Für die Ebene auf jeden Fall eine brauchbare Lösung. Ich vermute, die Zackenräder an der Hinterachse brauchst du für die nötige Traktion,
Die letzten Tage habe ich die Navigation von 5Hz auf 10Hz erhöht und noch versucht Quantifizierungs-„Fehler“ zu bereinigen - also Integer raus und durch Float ersetzen um möglichst geschmeidige Regelung zu bekommen - Feldtest steht aus.
Die Zackenräder an der Hinterachse sind noch aus der 2 Rad Antriebszeit. Ich werde die mal abbauen wenn das Gesamtgewicht auf die Räder drückt. Ich denke aber die Hinterräder müssen einen gewissen Grip haben. Ein normales BobyCar Rad muss ja nur rollen. Ein Ausfall meines 3D Druckers wäre für mich ein Albtraum. Auch wenn er nur klein ist. Für mich unverzichtbar.
Was ich bei Deiner Navigation noch nicht ganz verstehe. Dein "Arnold" fährt doch sehr langsam - jedenfalls auf den Videos die ich bisher gesehen habe - Du kämst doch locker mit 1Hz update Rate aus, oder? Wie viele cm legt Arnold in einer Sekunde zurück? 5 Hz wären da doch schon super genau, oder habe ich da einen Knoten im Kopf?
Gruß & schönen entspannten kühlen Sonntag.
 
Der Rover fährt grundsätzlich sehr langsam, weil der Fürst eine zu hohe Übersetzung des Getriebes ausgewählt hat. Fährt der Rover von allein ist das nicht schlimm, fährt der Fürst von Hand, ist er dann meistens genervt.
Maximalgeschwindigkeit ist 0,3m/s. Bei 5Hz = 200ms fährt der Rover 6 cm weit. Allerdings kommt die Koordinaten-Differenz nur zu einem Teil in der Lenkung an - dazwischen liegen Lenksignalglättung, Regler-Eingriffsglättung, Antriebs-Glättung, Kalmanfilter. Selbst das GPS-Signal hat eine Schwankung. Das bedeutet, der Rover fährt also schon eine deutlich größere Strecke als es die Werte im ersten Moment Glauben machen. Bei langsamer Fahrt, wie auf dem Video mit ca 50%, sind das vielleicht 15cm Fahrstrecke in der Realität und bisher 20cm Toleranzvorgabe. Da sieht man, welche Reaktionsgeschwindigkeit dann erforderlich ist. Auf ebener Strecke funktioniert das gut. Ich habe versucht, die Mittelwertbilder und Filter auf möglichst kleine Werte (zB. =3) zu reduzieren und jetzt noch die verloren gegangene Genauigkeit bei Umrechnungen von Float zu Integer zu eliminieren, das hat auch deutlich die Genauigkeit beim Abfahren der Maurerschnur erhöht. Dennoch läßt sich das nicht beliebig steigern, weil sonst die Lenkung anfängt zu flattern und das mechanisch das Fahrwerk überlastet. Es geht schneller aber dann zu Lasten der Genauigkeit. Bei steigender Geschwindigkeit ist die Herausforderung die Parameter so zu wählen, daß man exakt zwischen Schwingen um und Abtriften von der Ideallinie liegt. Mit der bisherigen Geschwindigkeit kann man mähen, aber einen guten Eindruck macht das nicht. Im Moment sieht man ein Ruckeln des Antriebs, was auf die vielen Lenkbewegungen zurück zu führen ist. (Den Effekt von Integer zu Float habe ich noch nicht gesehen.) Ich denke, die Maurerschnur legt da schon die Schwächen offen. Normalerweise sieht man vielleicht, daß der Rover nicht so genau auf einer Linie fährt aber wie weit er abweicht läßt sich schwer einschätzen. Der große Unterschied bei diesem/n Konzept/en ist, daß der Rover gezielt von Punkt zu Punkt fährt. Bei den kommerziellen Mähern ist das (vermutlich) anders geregelt. Die fahren schöne gerade Bahnen und achten auf Grenzen. Ob die Bahn jetzt seitlich versetzt ist, spielt weniger eine Rolle.
Ich denke darüber nach, ob ich die Odometrie stärker berücksichtigen soll um gerade Linien zu fahren, aber das ist mit dem Lenkungsprinzip eine große Herausforderung. Hätte ich einen Servo an der Lenkung (so einen, der >100€ kostet und nur einen Tag hält) dann wäre die viel steifer und würde nicht durch kleine Steine, Mulden usw. seitlich verzogen/ausgelenkt, was dann sofort wieder korrigiert werden muß. Es ist aber auch zu überlegen, ob der Mäher nur gerade Linien fahren muß. Es wäre auch denkbar, die Fahrstrecke über mehrere Wegpunkte in Kurvenfahrt zu berechnen. Das wollte ich zum aktuellen Zeitpunkt nicht, weil ich dann nicht die wirkliche Genauigkeit abschätzen kann.
Die Azurite-Software vom Ardumower pendelt bei der Fahrt entlang des Perimeters permanent um den Draht. Für mich war/ist die Geschwindigkeit der Hinterachs-getriebenen Mäher beeindruckend. Das habe ich mit der lenkenden Vorderachse nur sehr kurze Zeit abbilden können. Mit Servoantrieb ist der Servo so im Dauerstreß, daß er innerhalb einer Stunde das zeitliche segnet, ohne Servo müssen die Räder so hart angesteuert werden (also bei der recht hohen Fahrgeschwindigkeit) daß das einen Eindruck eines Schlagschraubers vermittelt. Daran ist auch mein Antrieb mit Schrittmotoren gescheitert. Die Schrittmotoren haben manchmal bei hoher Last zB. am Hang Schritte verloren, trotzdem hat der Mäher gut funktioniert. Aber die Schrittimpluse haben sowohl die Kunststoffräder zerlegt, als auch alle Befestigungselement auf den Achsen. Dauerthema war Rad kaputt oder Rad verloren -> Projekt eingestellt, Mäher geschlachtet.
Mein blauer Mäher - ChargerFR oder Prototyp-5 ist jetzt auf dem neusten Stand. Er hat noch nie den Rasen gesehen. Er fährt deutlich schneller als der rote Mäher - Arnold (der Starke) oder Prototyp-4. Morgen werde ich den roten aktualisieren und dann mit beiden mal Testfahrten absolvieren. Ich werde berichten.
Es grüßt
Fürst Ruprecht
 
Last edited:
Ulli,
ich hätte da mal eine Frage zu Deinem Heading. Wie berechnest Du das Heading? Nimmst Du es aus dem Sensor ohne nachgelagerte Verarbeitung oder durchläuft es eine Tilt- oder Mahony-Filterung? Wenn ja, wie hoch ist deine Abtastfrequenz und wie sind deine Verarbeitungsparameter?
Gruß Fürst Ruprecht
 
Ulli,
ich hätte da mal eine Frage zu Deinem Heading.
Beim Heading (meine Definition: Das ist die Ausrichtung des Mähers gemäß Kompass / Himmelsrichtung) da mache ich folgendes.
Beim Einschalten wrd der BNO085 kurz kalibiriert. i.d.R klappt das schon ohne Bewegung, der BNO ist da sehr gut. Ist er kalibriert, dann wird der Wert vom Kompass als GyroKurs festgesetzt (Zeile 251 in der BNO085.py). Ab diesem Zeitpunkt arbeite ich nur noch mit dem Gyro weiter.
Danach wird alle 200ms dieser Wert in die /dev/shm/bno_heading Datei geschrieben. Mit diesem Wert arbeitet meine Navigation rtk_navi.py als Heading Wert wenn der Mäher sich nicht bewegen würde.
Nun stellt aber das RTK Modul fest, dass sich der Mäher bewegt wenn er los fährt und schneller als 15cm/s aber das Delta aus den letzten Positionen kleiner als 0.8m ist (das kann passieren wenn er zwischen RTK-Fixed und RTK-Float hin und her springen würde dann kann das delta schon mal größer sein und würde einen flaschen heading wert liefern.) dann passiert folgendes: In die Datei /dev/shm/gyro.kurs wird der rtk-heading wert geschrieben.
# Gyro neu synchronisieren
if gyro_sync == False and rtk["fix"].startswith("RTK") and Motorspeed > 15 and rtk["delta"] < 0.8:
log("[Gyro Sync] *****************************************************************")
log(f'[Gyro Sync] Gyrokurs= {bno["GyroKurs"]:4.1f} Delta zu GPS = {norm_angle_deg((rtk["heading"]-bno["GyroKurs"])):2.1f} Setze Gyro auf {rtk["heading"]:.1f}° Fix={rtk["fix"]}')
log("[Gyro Sync] *****************************************************************")
#msg=f"[Gyro-Synced] GPS-Heading= {gps_heading:4.1f} GyroKurs= {gyroKurs:4.1f} Delta= {(gps_heading-gyroKurs):2.1f} MagKurs= {MagKurs:4.1f} YAW= {YAW:4.1f}"
with open("/dev/shm/gyro.kurs", "w") as f:
f.write(str(rtk["heading"]))
gyro_sync = True
Und damit arbeitet nun der Gyro weiter und stellt ja alle 200ms fest ob sich die Ausrichtung ändert, und schreibt dann seinen aktuellen Wert wieder in die bno_heading Datei. Das ist stabiler, als wenn ich mit dem rtk-heading wert arbeiten würde, der wird ja bei mir im Moment durch mein RTK-Modul nur jede Sekunde aktualisiert. Die rtk_navi.py schaut dann wieder in der bno_heading nach welchen Wert dort steht. Sie hat aus der /dev/shm/rtk_point.json die aktuelle Lat/Lon herausgeholt und weiß aus der waypoint Liste wo sie hin muss. Daraus kann sie dann für die Motorsteuerung die erforderlichen Werte berechnen, und schreibt diese dann jede sekunde cmd= f"20, 20, {int(distance*100)},s,{int(target_bearing)}" in die /dev/shm/drive_cmd. Die Motorsteuerung liest die dann auch wieder aus und aktualisiert damit dann in diesem Beispiel 20 20 mit den erforderliche rpm Werten die sich aus dem target_bearing und dem aktuellen heading (welches auch die Motorsteuerung aus der bno_headimg Datei ausliest) ergibt. In den Dateien im zip File ist noch sehr viel logging information enthalten, was ich zur Analyse gebraucht habe. Das müsste ich dann mal bereinigen.Hoffe ich konnte Dir helfen.
 

Attachments

Gestern habe ich dann endlich einmal mehrere Fahrten zur Bestimmung der Spurtreue absolviert. Also wie der @Fürst Ruprecht mit der Maurerschnur es dokumentiert hat. Eine Crosstrack Erkennung ist in meinem Python Script zwar implementiert, aber ich speise den ermittelten Fehler noch nicht in die Regelung zur Spurkorrektur ein. Ob das bei dem LC29-HDA wegen der 1Hz Korrektur Sinn macht wäre noch auszutesten. Das LC29-HEA ist aber schon angekommen und wartet auf den Einbau.
View attachment CrossTrack.mp4
Auf Jeden Fall lässt sich schon einmal gut erkennen, dass er auf den ca 6 Metern (das ist die vordere Lange Strecke auf dem IPad Screen) gut annavigiert hat und dann entlang der Maurerschnur entlang fährt. Man kann auch erkennen dass die RTK Antenne in Fahrtrichtung gesehen rechts von der Mitte verbaut ist, diese 20cm habe ich softwaremäßig korrigiert. Zum Ende der Fahrt sieht man, dass die Regelung stärker auf die Fahrtrichtung einwirkt. Der Grund liegt darin, dass ich im Moment als Wegepunkt en Zielpunkt annaviegiere, und sekündlich korrigiere ob die Richtung noch gehalten wird. Je kürzer die Entfernng zum Ziel ist, um so stärker sieht man dann das Ergebnis. Diesen Test habe ich ca 10x wiederholt und Crossträck Fehler von bis zu -16cm also rechts der Maurerschnur bzw. 18cm links von der Maurerschnur gemessen. Ich finde für ein 1Hz Modul sind das schon gar nicht so schlechte Ergebnisse. Was ich jetzt schon ändern könnte, wäre die Erkennung wann das Ziel erreicht ist. Das habe ich derzeit fest auf 30cm eingestellt. Also wenn die erkannte Position in einem Radius von 30cm um den Zielpunkt ist, dann liest er das neue Ziel ein und navigiert dort hin. An dieser log zeile kann ich lesen dass er ca.-0.089m also ca 10 cm rechts der Ideallinie entlangfährt und noch beim letzten log 52cm bis zum Ziel zu fahren hat. ich könnte also eine "adaptive" Zielerkennung implementieren.
16:27:50 {'Track_id': 3, 'cross_track': -0.097, 'along_track': 5.52, 'remaining': 0.746}
16:27:51 {'Track_id': 3, 'cross_track': -0.089, 'along_track': 5.74, 'remaining': 0.52}
Wenn er also bei den ca 10cm CrossTrack Fehler auf den letzten cm zum Ziel bleibt, könnte ich ihm einen Zielradius von 15cm definieren, das wäre dann doppelt so gut wie jetzt und würde noch immer genügend Toleranz zulassen. @Fürst Ruprecht wie hast Du das für Deine Kutschen des Hofes gelöst?
 
Antwort als PDF - anders bekomme ich es nicht hin 😟, ist vielleicht auch zu umfangreich für einen einzelnen Beitrag.
Tausend Dank für die ausführliche Beschreibung. Bis auf die Kurvenfahrten haben verfolgen wir eine ähnliche Logik. Kurven fahrten habe ich noch überhaupt nicht implementiert. Das einzige wo ich Kurvenfahrten sehe sind die Perimeterschleifen um Bäume und Blumensträucher auf dem Rasen. Das will ich dann angehen wenn ich mit meiner Geanauigkeit zufrieden bin. Am Sonntag hatte ich z.B. sehr schlechte RTK Qualität, Das fing schon mit dem Fix unter freiem Himmel an der benötigte mehre Minuten und wenn er beim Mähen ab und zu auf Float umspringt leidet auch die genauigkeit. Daher würde ich da nicht perfektionieren wollen. Im Moment stelle ich mir die Implementierung meines Reglers zum minimieren des Queranteils so vor:
Der vorhandene Regler für die Richtung auf den PWM Anteil der Antriebsräder. Mein Konzept ist wie beim Autofahren.
Ich gebe Gas (habe einen Verbrenner) fahre z.B. Tempo 30. Mit meinem Fuß versuche ich das tempo zu halten. das macht der PWM PID Regler. Beide Räder sollen die Geschwindigkeit von z.B. 28rpm halten. Nun kommt noch die richtung ins spiel. Muss er aufgrund des Headings weiter nach rechts, so wird die Linke Soll Geschwindigkeit auf z.B. 30rpm und die rechte auf 26 gesetzt. damit setze ich also eine neue Soll geschwindigkeit für die Rader. Jetzt kommt dann noch der Regler für den Querfehler hinzu. er setzt genauso wie der Heading regler die Soll RPM der Räder, ich werde ihm aber einen Faktor noch zusätzlich geben.
Das muss ich aber noch empierisch ermitteln. Diesen Regler will ich als nächstes Feature implementieren. Der Faktor wird umso größer sein, je weiter ich vom Zielpunkt entfernt bin. Damit will ich erreichen, damit er schnell seine optimale Bahn findet. Da es bei uns in QWL derzeit trocken und nicht zu heiß ist, habe ich das Ziel das diese woche noch zu Implementieren. Derzeit kann ich sagen dass ich mit dem Geradeauslauf schon sehr zu frieden bin. Das hat man an der Maurerschnur ja gesehen, aber er soll die Bahn halt optimal treffen.
Ich denke auch, dass ich sicher dieses Jahr noch immer mit meinem Routen-Editor die Bahnen vorgebe die er fahren soll also WegePunkt zu Wegepunkt. IM kommenden Jahr wäre dann das Ziel dass er selber die Bahnen berechnet und dann diese abfährt. Aber zwei Funktionen muss ich dazu noch implementeren.
a-) Wenn er bei der Anfahrt auf einen Zielpunkt auf ein Hindernis stößt, dann versucht er dieses zu umfahren. Hier hat sich gezeigt, dass es bei ungünstiger Position sinnvoller wäre den eigentlichen Zielpunkt zu verwerfen und den nächsten Zielpunkt anzunavigieren. Stelle ich mir so vor, dass ich die Verusche beim Ausweichen zähle, hat er es 5mal versucht merkt er sich das nicht erreichten Zielpunkt fährt aber zum nächsten.
b-) Im Moment bekomme ich - und er - noch nicht mit wenn er irgendwo hängen bleibt. Werden die Motore bestromt aber ist die Position nach 2 Sekunden noch immer die selbe, dann sollte er piepen und mich benachrichtigen @SefanH hast Du da nicht etwas für Whatsapp gebaut, welchen Dienst nutzt Du?, ich war da bisher noch nicht erfolgreich.
Also noch mals vielen Dank für die Niederschrift des Konzeptes.
Gruß Ulli
 
Back
Top