Hei, danke Andun für das ausführliche Review! Heeeftig!
Also den Unterschied zwischen int und long versteh ich auch überhaupt nicht. Gaaanz komisch. Ich probiers auch gleich mal aus (Nachtrag kommt ) Wegen den Helligkeitsunterschieden kann ich mal folgende Formel angeben, mit der ich etwa den Faktor quadteiler geschätzt habe:
quadteiler = (maximaler Helligkeitsunterschied)²/(medspeed+maxspeed)
Warum medspeed+maxspeed? Weil, falls du diesen Wert von der durchschnittlichen Motordrehzahl abziehst, du an der untersten negativen Kante des Motors landest.
Bei mir ist der maximale Helligkeitsunterschied etwa nur 100 und medspeed+maxspeed = 250. Also quadteiler=10000/250=40. Bei dir wäre es dann eine ganz andere Liga an Teiler: 360000/250=1440 (!!!). Auch wenn du 100 als quadteiler verwendest, dürfte der Asuro sich noch den Allerwertesten abwackeln! Evtl sollte ich die Formel mal mit ins Proggi reinschreiben, wird verständlicher. Probiers mal aus!
Noch zwei andere Ideen hatte ich (um die Linie evtl noch schneller abzufahren): 1. mal ne kubische Abhängigkeit probieren (ich glaub allerdings, das dürfte zu heftig werden und ähnlich wie ein/abschalten des Motors wirken) und 2. adaptive MedSpeed im Sinne von: Wenn du (der Asuro) merkst, das du gerade aus fährst (sprich i relativ klein) schraub die Drehzahl hoch, bis der Unterschied wieder größer wird.
Dürfte beides nicht allzu schwer zu implementieren sein. Nur mach ich mir bei beiden Ideen Sorgen um die Stabilität (nicht, das er dann nach der 5. Fahrt doch noch ausbricht...).
So, schreib ich gleich nochmal.
1. Nachtrag:
Also was sofort bei Umstieg aller ints auf long auffällt: Die .hex wird deutlich größer!! Ist ja irgendwie auch klar. Nur: Reagiert der Asuro dann einfach zu langsam, weil er zuviel zu rechnen hat? Hab mal als "Taktanzeiger" eine der BackLeds mit drangehängt (direkt in der for(; Schleife). Ist aber kein Prob, die BackLED leuchtet noch durchgehend (also sicher noch (f Takt) > 100 Hz.
Mal hier eben ne blöde Frage nebenbei: Wieviel passt in den Asuro rein? Sprich: Wieviele Pages kann man über das Flashtool übertragen bzw. wie groß darf die .hex maximal sein?
Wegen den Probs mit long: Denke, es gibt Probs bei i = lineData[0] - lineData[1]; Hier werden zwei unsigned Ints (müssen Ints sein!) voneinander abgezogen und dann als eine signed long übergeben. Da muss es Schwierigkeiten geben, weil das Vorzeichenbit einfach als Zahl mit rüber kommt. Abhilfe: Statt unsigned int lineData[2]; als Definition einfach nur int lineData[2]; angeben. Der negative Bereich ist zwar nicht benötigt, aber so umgeht man die sonst notwendige Konvertierungsroutine.
So, Prob gelöst, Asuro läuft jetzt komplett auf long-Variablen völlig problemlos (zumindest hier bei mir). Um RAM zu sparen kann man später mal noch die Variablen auf long und int wieder aufteilen.
Aktualisierter Code für dich, Andun, und andere Interessierte:
2. Nachtrag:
War ja wohl sooooowas von klar, das ein zweiter Nachtrag kommt! So, hier jetzt dann erstmal der letzte Code für heut. Erstens hab ich mal nur i und die beiden Speeds auf long gelassen, um RAM zu sparen. Dürfte ausreichen, wenn nicht, müsste das wieder geändert werden.
Wichtiger: Nach dem Einsehen, das der quadteiler eigentlich *die* wichtige Variable in dem Proggi ist, hab ich sie über die Switches einstellbar gemacht. Es gibt jetzt einen quadinit, die entsprechend dem beschriebenen Schätzwert eingestellt wird und eine Variable quadteiler, die je nach quadinit über die Switches eingestellt werden kann (Sw1: quadteiler=quadinit/8 ... Sw6: quadteiler=quadinit*4). Das hat einige Vorteile: Erstens kann der Schätzwert eher mal untermauert/wiederlegt werden, ohne 50ig mal zu programmieren, zweitens kann der Asuro auf die jeweilige Bahn getrimmt werden (nur scharfe Kurven: Sw1 -> durch die Gegend wackel, eher Geraden und lange Kurven: Sw6 -> düüüüs).
Der Code dazu:
Code:
#include "asuro.h"
#include <stdlib.h>
#define maxspeed 130 /* gibt sowohl die maximal positive als auch die maximal negative
Geschwindigkeit an, guter Mittelwert etwa 140 */
#define medspeed 120 /* gibt die den Durchschnitt der Geschwindigkeit beider Seiten an,
guter Mittelwert etwa maxspeed-20 */
//zur Variable quadinit (fast schon wichtigste Variable!!):
/* Quotient des Liniensensors. Umso niedriger desto mehr neigt der
Asuro zum "Wackeln" auf geraden Strecken, aber er nimmt auch engere Kurven. Umgekehrt umso
höher dieser Wert, desto schneller fährt der Asuro die Strecke ab (ohne Wackeln), aber es
werden zu enge Kurven "überfahren". Einen Schätzwert erhält man über die Formel
quadinit = (maximaler Helligkeitsunterschied)²/(medspeed+maxspeed) , wobei der maximale
Helligkeitsunterschied von Asuro zu gemodetten Asuros sehr groß werden kann und bekannt sein
sollte! Bei mir: ca. 100 (damit quadinit=40), bei bspw. Anduns Asuro: 600 (und damit
quadinit=1440 (!))
Über die Kollisionstaster können verschiedene quadteiler ausgewählt werden (je nach abzufahrender Bahn)*/
/*ToDo: Kubische Abhängigkeit ausprobieren, adaptive medspeed abhängig von i*/
long i, speedLeft, speedRight;
char flag, sw;
int lineData[2], quadinit = 30, quadteiler, sR, sL;
void Line (void)
{
speedRight = medspeed - ((i*abs(i))/quadteiler);
speedLeft = medspeed + ((i*abs(i))/quadteiler);
if (speedRight > maxspeed) speedRight = maxspeed;
if (speedLeft > maxspeed) speedLeft = maxspeed;
if (speedRight < -maxspeed) speedRight = -maxspeed;
if (speedLeft < -maxspeed) speedLeft = -maxspeed;
if (speedRight < 0) {MotorDir (FWD,RWD); sR=-speedRight;sL=speedLeft;}
else if (speedLeft < 0) {MotorDir (RWD,FWD); sL=-speedLeft;sR=speedRight;}
else {MotorDir(FWD,FWD);sL=speedLeft;sR=speedRight;}
}
int main(void)
{
Init();
quadteiler=quadinit;
flag=0;
FrontLED(ON);
for (i = 0; i < 0xFF; i++) LineData(lineData);
speedLeft = speedRight = 120;
for(;;) {
if (flag=1) {flag=0; BackLED(ON,OFF);}
else {flag=1;BackLED(OFF,OFF);}
sw = PollSwitch();
sw = PollSwitch();
sw = PollSwitch(); //wird nur zum korrekten Auslesen 3x aufgerufen
if (sw > 0)
quadteiler=quadinit/8;
if (sw > 1)
quadteiler=quadinit/4;
if (sw > 2)
quadteiler=quadinit/2;
if (sw > 4)
quadteiler=quadinit;
if (sw > 8)
quadteiler=quadinit*2;
if (sw > 16)
quadteiler=quadinit*4;
LineData(lineData);
i = lineData[0] - lineData[1];
if (i > 0) {
StatusLED(GREEN);
Line();
}
else if (i < 0) {
StatusLED(RED);
Line();
}
else {
StatusLED(OFF);
speedLeft = speedRight = medspeed;
MotorDir(FWD,FWD);
sL=speedLeft;sR=speedRight;
}
MotorSpeed(sL,sR);
}
}
Lesezeichen