archimedische Spirale fahren?

slatkow11 schrieb:
Hi,
Könnte man das nicht so machen, das wenn der Mowerstrom hoch geht, er also hohes Gras hat, anfängt die Spirale zu mähen und das so lange macht bis die Schleife erreicht ist oder der Bumper ausgelöst wird ?

Das macht auf alle Fälle Sinn. Aber man sollte auch darauf achten das der Mäher ein paar Meter fährt bevor die nächste Spirale möglich ist, sonst fährt er immer wieder über eine bereits gemähte Fläche drüber.

Ergibt schöne Kornkreise :D
 
Zuletzt bearbeitet von einem Moderator:
Wenn er mit der Spirale fertig ist, sollte er ja erst wieder auslösen, wenn das Grass zu hoch ist.

motorMowPowerNormal = 60.0; // motor mower max power (Watt)

void Robot::checkMowCurrent(){
if (millis() < nextTimeCheckCurrent) return;
nextTimeCheckCurrent = millis() + 100;

if (motorMowSense >= motorMowPowerNormal){
setNextState(STATE_CIRCLE,0);
}

}
 
Ich denke man könnte alles außer Azurit aus meinem Fork auch rausnehmen. Da ich erst angefangen habe mich mit Git zu beschäftigen, lasse ich es erstmal so wie Github das vorsieht. Anbei aber der direkte Azurit-Link:
https://github.com/ainagtur/ardumower/tree/master/code/ardumower
Ist der Motorstrom wirklich sensitiv genug? Ich kann mir schwer vorstellen, daß er merklich ansteigt wenn das Grass länger wird. Zum starten der spiralfahrt müsste man in dem jetzigen Code statt

Code:
setNextState(STATE_CIRCLE,0);



Code:
motorSpiralStartTime = stateTime;


setzen, dann fängt die Spirale an (ohne, daß ich es jetzt wirklich getestet habe...)

Vielleicht funktioniert es wenn man motorMowPowerNormal im stehen ausmisst und dann auf starke Änderungen während der Fahrt reagiert.


Ich lasse ihn zur Zeit viele überlappende Kornkreise damit wirklich keine einzelne Grasbüschel mitten in der Fläche stehen bleiben und es funktioniert mMn. effizienter als einzelne Zufallsbahnen. Da habe ich mich immer geärgert, wenn er schon wieder knapp an so einem Büschel vorbeigefahren ist.
Wenn es dann irgendwann mit dem Partikel Filter läuft, dann wird es erheblich zeiteffizienter.
 
Mein Mähmotor benötigt bei kurzem Gras 20W. Wenn er auf 45W ansteigt, fahre ich langsamer. Wenn er dann wieder unter 30W fällt, fahre ich wieder schneller. Wenn er über 75W zieht, schalte ich ihn für 30Sek. ab. Funktioniert bisher ganz gut.
 
Ich musste meinen Motor auch auf 100 W stellen, damit er durch das hohe Grass gemäht hat.
Das war ja auch mal die Idee hinter der Messermodulation.

@Roland wie hast du das langsam fahren umgesetzt ?
 
Ich verwende meine eigene Software. Ich berechne im Vorfeld, welche Geschwindigkeit für die aktuelle Gegebenheit notwendig ist, speichere diese auf dem Blackboard in die Variable cruiseSpeed und sende diese dann an den Motor.

GeschwindigkeitSetzen.JPG

Attachment: https://forum.ardumower.de/data/media/kunena/attachments/2936/GeschwindigkeitSetzen.JPG/
 
Zuletzt bearbeitet von einem Moderator:
Vielen Dank für den Hinweis zum Mähmotor! Ich habe drauf geachtet wie sich der Motorstrom bei gemähten / ungemähten Bereichen ändert. In bereits gemähten Bereichen ist er bei mir zwischen 3 und 10 W, Anstieg auf >15W (motorMowPowerThreshold ) dient jetzt als Auslöser für die Spiralfahrt nachdem eine Mindeszeit von motorSpiralStartTimeMin gefahren wurde. Diese neuen Parameter lassen sich über pfod anpassen und werden jetzt auch im EEPROM gespeichert.

Wikiseite und Azurit Fork wurden upgedated.
 
Ich habe zusätzlich nun noch die Geschwindigkeit angepasst in Abhängigkeit des Radius. Je größer der Radius, je schneller fährt der Robbi.
Und ich habe den Radius begrenzt .


Code:
//forums.parallax.com/discussion/154274/the-artist-robot/p5
class TCruiseSpiral: public Node    // Each task will be a class (derived from Node of course).
{
private:

    uint32_t lastTimeExecuted;

    float speedOuter;
    float speedInner;

    float waitUntilOuterCmReached;

    float r;
    float addRadius;

    float segments;
    
    float MAX_SPIRAL_RADIUS;

public:

    TCruiseSpiral () {

        segments = 16.0f; // How often should the calculation be done within 360 degrees. 16 Means every 22,5 degrees. This means that 360 is splited in 16 segments
        addRadius = 17.0f/segments; // Radius that should be increased in one round divided by 16 because every 22° the speed and cm will calculated new. I chose 35.5/2=17 in because the cutter disc should overlap each round.
    }

    virtual void onInitialize(Blackboard& bb) {
        r = 22.0f; //22.0f; // Start with bigger radius in order not to stall the inner wheel 35.5

        calcSpeed(r,bb);
        calcOuterCm(r);
        bb.motor.startDistanceMeasurementSpiral();
        bb.motor.L->setSpeed(speedOuter);
        bb.motor.R->setSpeed(speedInner);
        bb.driveDirection = DD_FORWARD;
        MAX_SPIRAL_RADIUS = GETTF(TF_MAX_SPIRAL_RADIUS_CM);
    }

    void calcSpeed( float _r,Blackboard& bb) {
        float d = GETTF(TF_DISTANCE_BETWEEN_WHEELS_CM);
        
        speedOuter = mapf(_r,  22.0f, MAX_SPIRAL_RADIUS , bb.CRUISE_SPEED_MEDIUM, bb.CRUISE_SPEED_HIGH);
        bb.cruiseSpeed= speedOuter;
        speedInner= speedOuter * (2*_r-d) / (2*_r+d);
    }

    void calcOuterCm( float _r) {
        float d = GETTF(TF_DISTANCE_BETWEEN_WHEELS_CM);
        waitUntilOuterCmReached = (PI * (2*_r+d))/segments; // cm for 360 degree divided by 16 to get cm for 22,5 degrees
    }

    virtual NodeStatus onUpdate(Blackboard& bb) {
        // get the driven distance: bb.motor.getDistanceLInCM() and check if it has driven the calculated way: waitUntilOuterCmReached
        if (bb.motor.getDistanceLInCMSpiral() > waitUntilOuterCmReached) {
            bb.motor.startDistanceMeasurementSpiral();
            r+=addRadius;
            calcSpeed(r,bb);
            calcOuterCm(r);
            bb.motor.L->setSpeed(speedOuter);
            bb.motor.R->setSpeed(speedInner);
        }

        if(r > MAX_SPIRAL_RADIUS ) { // Stop Spiral after 150cm radius
            return BH_SUCCESS;
        }

        return BH_RUNNING;
    }

    virtual void onTerminate(NodeStatus status, Blackboard& bb) {
        bb.flagCruiseSpiral = false;
        bb.lastTimeSpiralStarted = millis();
    }

};


Anstatt feste Werte einzustellen, misst der Automower laut Beschreibung die durchschnittliche Belastung des Motors und und wenn diese überschritten ist, fährt er eine Spirale. Mit Intensität kann man dann festlegen, wie häufig eine Spirale gefahren wird. Aktuell weiß ich aber nicht, ob Intensität auf die Belastung bezogen ist oder auf eine Wartezeit zwischen den Spiralfahrten.
 
Mein Robbi hat sich eingegraben. Vermutliche Ursache: Er hat die Spirale gestartet und somit habe ich dieses als vorwärts fahren definiert. Nun ist die Kurve aber so eng, dass das Heck gegen den Brunnen gefahren ist. Da er dachte, er fährt vorwärts, wollte er nun ausweichen indem er zurückfährt. Ich habe das gelöst, indem ich eine Fahrtrichtung DD_SPIRAL_CW eingeführt habe. Wenn er bei dieser Fahrtrichtung den Bumper auslöst, fährt er eine starke Kurve CC 1,5 Sek zurück und bis der bumper frei ist.

Aktuell kann ich mir den Radstand des hintern Rades nicht erklären. Scheinbar ist er ein Stück zurückgefahren. Sonst müsste das Rad anders stehen. Vor dem Robbi sieht man dass er etwas gedreht zurückgefahren ist. Ich vermute, der rund Brunnen hat ihn hinten nach links gedrängt und dann hat er sich dort festgesetzt.

DSC_0445.JPG


DSC_0444.JPG

Attachment: https://forum.ardumower.de/data/media/kunena/attachments/2936/DSC_0445.JPG/
 
Zuletzt bearbeitet von einem Moderator:
Hallo,
ich habe deine Version aufgespielt und getestet. Super Sache das Mähen in Kreisbahnen. Gefällt mir sehr gut.
Erst mal vielen Dank dafür.
Ich habe noch einige Fragen denn so ganz läuft es noch nicht.
Wenn ich Odometrie einschalte flippt mein Mäher aus. Vorher hat es damit kein Problem gegeben? Er zuckt und bleibt nach kurzer Zeit stehen. Im Error Counter stehen dann Odemetrie Fehler. Muss ich noch was einstellen?
Wenn die Schleife erreicht wird dann stoppt der Mower so heftig, dass er hinten hoch geht. Beim Anfahren ist es ähnlich heftig?

Kannst du mir dabei weiter helfen?

Einen freundlichen Gruß
Hans Walter
 
Hallo Hans,

aktuell weiß ich nicht ob du mich ansprichst oder jemanden anderen.
Die Umsetzung der Interruptroutinen für den Mega waren nicht optimal. Der Code wurde geändert. Einfach mal auf github schauen.
Es kann sein das die PID Werte nicht auf deine Mower passen. Diese müssen vermutlich auch noch eingestellt werden.
Dann möglicherweise den IMU abschalten. Der benötigt wohl viel Rechenleistung.

Benutze das Board nicht. Ist nur was ich gelesen habe.
 
Hi,
im " Spiral " branch von meinem Fork ist nur die Spiralfahrt eingefügt, alles andere ist wie im normalen Azurit 1.07.
In dem master branch sind jedoch auch andere Sachen (wie das sofortige stoppen bei Bumper oder Perimeterüberfahrt) drin. Das würde die heftige Stoppen an dem Perimeter erklären.
Wenn das normale Azurit 1.07 mit der Odometrie läuft, dann sollten auch die Spiralfahrt aus dem " Spiral " branch eingentlich auch laufen. Ich habe die Geschwindigkeit bei mir jedoch auf etwa 30 rpm eingestellt, bei höherer Geschwindigkeit gab es seltsames Verhalten (liegt wohl an den nicht ausreichenden Odometrieinterrupts bei 1.2)

Die Spiralfahrt ist auch in dem SheepSheep Fork eingepflegt worden, da gab es Berichte über mehrere Ardumower die damit gut laufen.
 
Hallo Roland und gimate,
erst mal vielen Dank für die schnellen Antworten.
Ich werde erst mal mit IMU aus testen, ob das Verhalten besser wird?

Wenn keine Veränderung festzustellen ist, dann teste ich mal mit der Version ohne Änderungen.

Gruß HW.
 
Das Mähen mit der Spiralfahrt und Erkennung der ungemähten Flächen über den Mähstrom hat diesen Sommer wunderbar funktioniert. Was mich allerdings noch stört sind die kleinen Grass-Inseln in der Mitte der Spirale. Da alles Drumherum schön gleichmäßig runtergemäht wurde, ist die Wahrscheinlichkeit, daß der Ardumower über diese Inseln drübermäht recht gering, da musste ich öfters per Hand nachhelfen. [attachment=4237]IMG_20170910_09181.jpg[/attachment]

Ich habe die Spiralfahrt um eine weitere Zeit-Variable erweitert: motorSpiralStartTimeSecond. SpiralBranch Wenn der Ardumower eine Spiralfahrt anfängt, dann macht er zuerst eine kleine Spiralfahrt mit der Länge motorSpiralStartTimeSecond [ms]. Dann fängt er eine zweite Spirale an, die dann im bereits gemähten Bereich startet und das danebenliegende Zentrum der ersten Spirale abmäht. Die zweite Spirale erreicht dann bei mir etwa 1,5 - 2 m Durchmesser und hinterlässt eine vollständig gemähte Kreisfläche.
[attachment=4238]IMG_20170915_15022.jpg[/attachment]
Attachment: https://forum.ardumower.de/data/media/kunena/attachments/3847/IMG_20170915_15022.jpg/
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

ich habe auch mal deinen Branch getestet und komme damit leider nicht klar.
Odometrie funktioniert, bei mir garnicht. Er fährt einfach weiter gerade aus, selbst wenn ich den Button am Mower drücke.

Ich habe jetzt wieder die Version von Holorate / SheepSheep drauf gespielt und funktioniert super. Kann ich nur jedem Empfehlen.
 
Sorry, ich hatte den Brach als solchen nicht alleine getestet. Ich hatte es in mein master gemerged in dem auch all meine anderen Änderungen drin sind (2 Perimeterspulen, Bumperverhalten ...) und da hatte es bei mir schön funktioniert. Es wird wohl etwas aus einem der anderen Zweige fehlen, damit es richtig funktioniert. Da ich jetzt den Mega gegen ShiedlBuddy getauscht habe, kann ich es nicht mehr selber ausprobieren. Es wird wohl einfacher sein es z.B. in SheepSheep neu zu machen als den Fehler in meiner Version zu suchen.

Für den ShieldBuddy habe ich meine Modifikationen jetzt auch neu geschrieben, da zu viele Änderungen zwischenliegen.
 
Oben