• So ich bin langsam am verzweifeln. Ich bekomme den Besch... Kreutzmischer nicht zum laufen.
    Ich habe zwei Werte Kanal 1 (0-1023) und Kanal 2 (0-1023).
    Ich will wenn Kanal 1 = 0 ist und Kanal 2 = 512 daraus machen -> Kanal 1 = 0 und Kanal 2 = 0

    Ebenso Kanal 1 = 1023 und Kanal 2 = 512 daraus machen
    -> Kanal 1 = 1023 und Kanal 2 = 1023

    bei K1 = 1023 und K2 = 0 -> K1 = 1023 und K2 = 0

    Kann mir jemand helfen ich sitze jetzt seit 5 Stunden an dem Schrott und Exel gibt mir einfach keine schlüssigen Werte!

    Erfahrungen sind was sehr nützliches, leider macht man sie erst kurz nachdem man sie gebraucht hätte...

    • Offizieller Beitrag

    Hm... ich steh' hier mit Deinen Vorgaben etwas auf dem Schlauch.

    K1 = Lenkung ? K2 = Speed ? (also Eingänge?)
    Mittelstellung jeweils bei 512?
    Welchen Lenkungs-Faktor nimmst Du an? 50% ?

    Also: (?)
    Eingänge bezeichne ich mal als "I". I1 = Lenkung, I2 = Speed.
    Ausgänge als M1 (rechter Motor) und M2 (linker Motor).

    Somit:
    I1 = 512; I2 = 512 : M1 = 0% ; M2 = 0%
    I1 = 0 (Kreuzknüppel nach links); I2 = 512: M1 = -50% ; M2 = +50%
    I1 = 512 ; I2 = 1024 : M1 = +100% ; M2 = +100%.

    Sind wir mit den Vorgaben synchron? Dann könnte ich Dir einen Excel-Ansatz liefern....

  • Lenkungsfacktor soll bei 100% liegen. Wenn ich das mit der zweiten Formel rechne habe ich 100% Lenkung und 50% gas.
    Bei der ersten habe ich 100% gas und 200% Lenkung!
    Mache ich was falsch?

    Ich habe jetzt einfach in Exel -10 - 10 mit 0 als Mittelstellung genommen.

    M1 = I1+I2 und M2 = I1-I2 gibt Werte -20 - 20
    und
    M1 = I1/2+I2/2 und M2 = I1/2-I2/2 gibt Werte -10 - 10
    ergo nur halbe Kraft vorwärts. Kann ich bei der ersten Formel einfach die Werte auf 10 begrenzen und kann noch gut fahren?

    Irgendwie war das mit dem OP-Kreutzmischer einfacher.

    Erfahrungen sind was sehr nützliches, leider macht man sie erst kurz nachdem man sie gebraucht hätte...

    • Offizieller Beitrag
    Zitat

    Ich habe jetzt einfach in Exel -10 - 10 mit 0 als Mittelstellung genommen.


    Du musst unbedingt die Vorzeichen beachten, sonst kommst Du in den Wald... ;)

    Bei einem Kreuzknüppelausschlag nach links (keine Geschwindigkeit):
    M1 = -10 ; M2 = +10

    Bei einem Kreuzknüppelausschlag nach rechts (keine Geschwindigkeit):
    M1 = +10 ; M2 = -10

    Bei Vorwärts ohne Lenkung: M1 = +10 ; M2 = +10

    In der Software also eine Fallunterscheidung machen(, wenn die Werte keine Vorzeichen haben): Lenkeinschlag nach links oder Lenkeinschlag nach rechts.

    Nach links:
    M1 = I2 - I1 ; M2 = I2 + I1

    Nach rechts:
    M1 = I2 + I1 ; M2 = I2 - I1

    Problematisch wird's, wenn Du nicht die "Vollgas"/"Volllenkeinschläge" betrachtest, sondern Zwischenwerte. Dann muss der Fahrtregler nämlich die Bewegung stoppen, eine kurze Pause machen ("Pausenzeit bei Richtungswechsel") und dann die Gegenrichtung fahren.

    Beispiel:
    I1 = 0% ; I2 = 25% (also Schleichfahrt geradeaus nach vorne): M1 = M2 = 25%;
    Dann bei dieser Schleichfahrt einenLenkungseinschlag nach links mit 50%:
    I1 = 50% ; I2 = 25: M1 = -25% ; M2 = 75% ; => Der linke Motor muss stoppen und dann die Gegenrichtung drehen, während der rechte Motor keine Pause macht und von 25% auf 75% hochbeschleunigt.

    Zu Deiner Anmerkung mit den 200%: Ja, das kann theoretisch schon passieren. Das heißt, Du musst nach der Berechnung immer überprüfen, ob der Wert > 100% ist und dann abschneiden.
    Nachteil dabei: Der Bot schlägt bei solchen Extremsituationen Haken wie ein Hase. (M1 = 0% ; M2 = 100%)

  • Genau so soll es ja sein. Der Mischer sitzt ja in meiner Funke und wird noch von der Dualrate beeinflusst. Damit kann ich einstellen ob 100% oder 50% Lenkeinschlag gemacht werden kann.

    Erfahrungen sind was sehr nützliches, leider macht man sie erst kurz nachdem man sie gebraucht hätte...

    • Offizieller Beitrag

    Ok, soll ich Dir dann mal "allgemeines Blabla" darlegen, wie's bei mir mit festen %-Anteilen gemacht wurde?

    1) Eingangsgrößen:
    I1 = Lenkeinschlag-Wert
    I1R = Lenkeinschlag-Richtung (Links oder Rechts oder Neutral)
    I2 = Geschwindigkeit-Wert
    I2R = Geschwindigkeit-Richtung (Vorwärts oder Rückwärts oder Neutral)

    Ausgangsgrößen:
    M1 = Geschwindigkeit rechter Motor
    M1R = Drehrichtung rechter Motor (Neutral, vorwärts, rückwärts
    M2 = Geschwindigkeit linker Motor
    M2R = Drehrichtung linker Motor (Neutral, vorwärts, rückwärts

    (Soweit ich mich erinnern kann, hat Alex das anders aufgezogen. Bei ihm ist der Mittelwert des Bereichs-Ranges der Nullpunkt. Bei mir sind es zwei getrennte Größen von jeder Kreuzknüppel-Richtung.)


    2) Den Lenkeinschlag laut Deiner DualRate (?) festlegen.

    If (Dualrate)
    {
    I1 = I1 /2
    }

    3)
    Verzweigungen bilden, damit Du verschiedene "Bereichsblöcke" bilden kannst. Mag jetzt etwas aufwändig erscheinen, aber bei eventuellen "Funk-Mode-Wechsel" tust Du Dich mit Korrekturen leichter. Immer bedenken: Bei der Futaba-Funke ist die Änderung der PWM bei der Links-Rechts-Bewegung des Kreuzknüppels genau umgekehrt wie bei der Spectrum-Funke! Das führt dazu, dass vorwärts/rückwärts und auf der Stelle drehen wunderbar funktioniert. Aber bei "Mischbetrieb" fährt der Bot plötzlich in die falsche Richtung. ;)


    Also:
    If (I2==0) // Keine Vorwärts/Rückwärtsbewegung, somit auf der Stelle Drehen
    {
    ....If (I1<>0) // Wenn eine Lenkbewegung erwünscht ist
    ....{
    .........if (I1R == Links) // auf der Stelle nach links drehen
    .........{
    ...............M1 = I1
    ...............M1R = Rückwärts
    ...............M2 = I1
    ...............M2R = Vorwärts
    .........}
    .........else // auf der Stelle nach rechts drehen
    .........{
    ...............M1 = I1
    ...............M1R = Vorwärts
    ...............M2 = I1
    ...............M2R = Rückwärts
    ..........}
    .....}
    .....else // keine Fahrt und keine Drehung. Also Motoren abschalten
    .....{
    ..........M1 = 0
    ..........M1R = neutral
    ..........M2 = 0
    ..........M2R = neutral
    .....}
    }
    else // Es ist eine Fahrbewegung vorhanden
    {
    .....if (I1==0) // wenn keine Lenkbewegung vorhanden ist, dann die Eingangsgröße von I2 auf beide Motoren abbilden
    .....{
    ...........M1 = I2 // Geschwindigkeit auf rechten Motor übetragen
    ...........M1R = I2R // Fahrbewegung auf rechten Motor übertragen
    ...........M2 = I2 // Geschwindigkeit auf linken Motor übetragen
    ...........M2R = I2R // Fahrbewegung auf linken Motor übertragen
    .....}
    .....else // es ist sowohl eine Fahrbewegung als auch eine Lenkbewegung vorhanden
    .....{
    ..........If (I2 > I1) // Die Fahrgeschwindigkeit ist grösser als der Lenkeinschlag
    ..........{
    ...............If (I2R == vorwärts) // Vorwärtsfahrt, jetzt Lenkeinschlag berücksichtigen
    ...............{
    ....................If (I1R == Links) // Lenkeinschlag nach links
    ....................{
    ..........................M1=I1 + I2 // rechter Motor wird beschleunigt
    ..........................M2 = I2 - I1 // linker Motor wird abgebremst
    ..........................M1R = vorwärts
    ..........................M2R = vorwärts // nachdem das Gas größer ist als der Lenkeinschlag erfolgt kein Wechsel der Drehrichtung
    ....................}
    ....................else // es ist ein Rechtseinschlag gewünscht
    ....................{
    ..........................M1=I2 - I1 // rechter Motor wird abgebremst
    ..........................M2 = I2 + I1 // linker Motor wird beschleunigt
    ..........................M1R = vorwärts// nachdem das Gas größer ist als der Lenkeinschlag erfolgt kein Wechsel der Drehrichtung

    ..........................M2R = vorwärts
    ....................}
    ...............}
    ...............else // andere Lenkrichtung
    ...............{
    .....................// genau wie oben, nur eben andere Lenkrichtungen und Richtungswechsel
    ................}
    ...........}
    ...........else // Die Fahrbewegung ist langsamer als der Lenkeinschlag eine Bewegung hervorruft. Also muss jetzt beim kurveninneren Motor ein Drehrichtungswechsel erfolgen
    ...........{
    ...............If (I2R = vorwärts) // Fahrtrichtung ist zunächst vorwärts
    ...............{
    ....................If (I1R == Links) // Linkslenkung gewünscht
    ....................{
    ..........................M1=I1 + I2 // rechter Motor wird beschleunigt
    ..........................M2 = I1 - I2 // !!! der linke Motor darf nicht ganz die Drehrichtungsgeschwindigkeit haben, sondern wird um den Betrag der Vorwärtsrichtung vermindert
    ..........................M1R = vorwärts
    ..........................M2R = rückwärts // Lenkbewegung ist größer als Fahrgeschwindigkeit, also das Rad anders herum drehen
    ....................}
    ....................else // es ist ein Rechtseinschlag gewünscht
    ....................{
    ..........................M1=I1 - I2 // rechter Motor erhält die Geschwindkeit aus der Lenkbewegung abzüglich der Vorwärtsgeschwindigkeit
    ..........................M2 = I2 + I1 // linker Motor wird beschleunigt
    ..........................M1R = rückwärts
    ..........................M2R = vorwärts
    ....................}
    ...............} // Ende von Fahrtrichtung ist vorwärts
    ..............else // Die Fahrtrichtung vom "Gas" ist rückwärts, jetzt die Lenkbewung überlagern
    ..............{
    ................ // => im Prinzip wie oben, nur geänderte Bewegungsrichtungen
    ..............}
    .........}
    .....}
    }


    4) Limitierungen prüfen
    If (M1 > 255)
    {
    ....M1 = 255
    }
    If (M2 > 255)
    {
    ....M2 = 255
    }


    Die Profi-Programmieren werden jetzt die Nase rümpfen. Aber ich denke, als Anschauungsmaterial ist das soweit brauchbar.
    Der Gag ist, dass durch die Verzweigungen nachträglich noch eine "spezifische Funkenanpassung" erfolgen kann, wenn der Kreuzknüppel bei links/rechts plötzlich andere PWM-Richtungen hat.

    Es geht garantiert eleganter, aber das hier funktioniert und ist beim Durchlauf auch relativ schnell.

    @Mike: Das Beispiel war jetzt für Deine Vorgabe mit "-10" und "+10". Wenn Du über die Kreuzknüppel die Signale zwischen 0, 512 (=Mittelstellung) und 1024 (=Vollgas) kriegst, dann kann man das auch anders machen....

  • Läuft :D:D:D:D:D:D:D

    Val2=map(analogRead(Kanal_3), 0, 705, -100, 100); //und 5/1023*(minV) = Minimalwert und 5/1023*(maxV) = Maximalwert
    Val3=map(analogRead(Kanal_4), 0, 705, -100, 100); //z.B.: "Val0=map(analogRead(Kanal_1), 300, 800, 560, 1560);"
    x = Val2 + Val3;
    y = Val2 - Val3;
    x=map(x, -100, 100, 560, 1560);
    y=map(y, -100, 100, 560, 1560);
    Val2 = x;
    Val3 = y;

    if (x>100)
    {x=100;}
    if (x>-100)
    {x=-100;}
    if (y>100)
    {y=100;}
    if (y<-100)
    {y=-100;}

    Warum habe ich nicht von anfang an an sowas gedacht? Braucht so zwar mehr Rechenleistung aber dafür hat der ja fast 4ms Zeit.

    Den Servoausschlag limitiere ich per Hardware vor dem AVR. Deins muss ich mir mal in ruhe angucken.

    Erfahrungen sind was sehr nützliches, leider macht man sie erst kurz nachdem man sie gebraucht hätte...

    • Offizieller Beitrag

    Super ! Mit der Arduinio-Syntax bin ich zwar immer noch am überlegen, aber wenn's funktioniert, dann ist das der beste Beweis.

    Kann das richtig sein:

    Zitat

    if (x>-100 ) {x=-100;}

    Müsste das nicht "if (x <-100)" heissen? (Beim y stimmts)

  • Ups das war die noch nicht funktionierene Version. Das ist die richtige.

    if (digitalRead(X_Mischer) == HIGH) // X-Mischer für Kanal 3 und 4
    {
    Val2=map(analogRead(Kanal_3), 318, 703, -100, 100); //und 5/1023*(minV) = Minimalwert und 5/1023*(maxV) = Maximalwert
    Val3=map(analogRead(Kanal_4), 318, 703, -100, 100); //z.B.: "Val0=map(analogRead(Kanal_1), 300, 800, 560, 1560);"
    x = Val2 + Val3;
    y = Val2 - Val3;
    if (x>100)
    {x=100;}
    if (x<-100)
    {x=-100;}
    if (y>100)
    {y=100;}
    if (y<-100)
    {y=-100;}
    x=map(x, -100, 100, 560, 1560);
    y=map(y, -100, 100, 560, 1560);
    Val2 = x;
    Val3 = y;
    }


    Jetzt macht das auch Sinn! 318 und 703 sind unterer und oberer Potianschlag.

    Erfahrungen sind was sehr nützliches, leider macht man sie erst kurz nachdem man sie gebraucht hätte...