hallo zusammen
gleich vorweg:
noch mal ein thx an mare_crisium für die bescheibung eines brauchbaren reglers, aber sollte es nicht auch funktionieren, wenn ich das verhältnis der gefahenen wege bilde und dann dementsprechend die geschwindigkeiten änder? vorausgesetzt man wählt seine mindestgeschwindigkeit dementspechend
somit brauche ich nicht erst die drehzahl ermittel und auf diese reagieren (das spart vl etwas speicherplatz und zeit, wobei ich nicht weiß wie relevant das in diesem fall ist)
warum ich aber eigentlich schreibe:
wie oben schon berichtet hatte ich ein problem mit der integrierung der Arc-funktion in GoTurn.
durch experimentieren und mehrmaligem durchschauen des codes ist mir aufgefallen, dass ich "nur" ein MotorDir im Arc-Teil vergessen hatte, dadurch war er noch immer auf BREAK.
hier also der funktionierende code:
Code:
#include <asuro.h>
#include <myasuro.h>
//defines zur kurvenfahrt
#define BREITE 103 //spurbreite in mm
#define PI 3.141592
//defines, um alte variablennamern weiterverwenden zu können
#define distance length
#define radius length
#define winkel degree
#define enc_count count_a_soll
#define tot_count count_a
#define l_speed speed_a
#define r_speed speed_i
#define GO 1
#define TURN 2
#define ARC 3
void GoTurnArc (
int length,
int degree,
int speed)
{
StatusLED(RED);
unsigned long enc_count;
int count_a=0,count_i=0;
int diff = 0;
int speed_a=speed, speed_i=speed;
int radius_a, radius_i;
float quot, teiler;
long tik_summe;
int typ; //speichert den typ der gefahrenen strecke
/* stop the motors until the direction is set */
MotorSpeed (0, 0);
/* Go */
if (distance != 0 && degree == 0)
{
typ=GO;
/* calculate tics from mm */
enc_count = abs (distance) * 10000L;
enc_count /= MY_GO_ENC_COUNT_VALUE;
if (distance < 0)
MotorDir (RWD, RWD);
else
MotorDir (FWD, FWD);
}
/* Turn */
else if (distance == 0 && degree != 0)
{
typ=TURN;
/* calculate tics from degree */
enc_count = abs (degree) * MY_TURN_ENC_COUNT_VALUE;
enc_count /= 360L;
if (degree < 0)
MotorDir (RWD, FWD);
else
MotorDir (FWD, RWD);
}
/* Arc */
else if (distance != 0 && degree != 0)
{
typ=ARC;
/* calculate tics from distance and degree */
radius_a=radius+BREITE/2;
radius_i=radius-BREITE/2;
teiler=(float)360/abs(winkel); //Bruchteil des Kreises
quot=((float)radius_a)/((float)radius_i);
//berechnen der notwendigen tics am außen- und innenrad
count_a_soll=2*radius_a*(PI*10000L/teiler);
count_a_soll/=MY_GO_ENC_COUNT_VALUE;
MotorDir(FWD,FWD);
}
/* now start the machine */
if(typ!=ARC)
MotorSpeed (l_speed, r_speed);
else
{
//mindestgeschwindigkeit=70
if(speed<70) speed=70;
//anfangsgeschwindigkeiten berechnen
speed_a=speed;
speed_i=speed_a/quot;
//speed_i=speed;
//Motoren starten
if(winkel>0)
MotorSpeed(speed_i,speed_a); //im Gegenuhrzeigersinn
else
MotorSpeed(speed_a,speed_i); //im Uhrzeigersinn
}
/* reset encoder */
EncoderSet (0,0);
while (tot_count < enc_count)
{
if(typ!=ARC)
{
tot_count += encoder [LEFT];
diff = encoder [LEFT] - encoder [RIGHT];
/* reset encoder */
EncoderSet (0, 0);
}
else
{
//einen Tik abwarten
tik_summe = encoder [LEFT] + encoder [RIGHT];
while (tik_summe == encoder [LEFT] + encoder [RIGHT]);
//Odometrie einlesen
if(winkel>0)
{
count_a=encoder[RIGHT];
count_i=encoder[LEFT];
}
else
{
count_a=encoder[LEFT];
count_i=encoder[RIGHT];
}
diff=count_a-(count_i*quot);
if(winkel > 0) diff*=-1;
}
if (diff > 0)
{ /* Left faster than right */
if ((l_speed > speed) || (r_speed > 244))
l_speed -= 10;
else
r_speed += 10;
}
if (diff < 0)
{ /* Right faster than left */
if ((r_speed > speed) || (l_speed > 244))
r_speed -= 10;
else
l_speed += 10;
}
if(typ!=ARC) MotorSpeed (l_speed, r_speed);
else
{
if(winkel>0)
MotorSpeed(speed_i,speed_a);
else
MotorSpeed(speed_a,speed_i);
}
Msleep (1);
}
MotorDir (BREAK, BREAK);
Msleep (200);
}
der code ist zwar noch etwas verbesserungsfähig, aber es funktioniert endlich
was mir beim ausprobieren noch aufgefallen ist:
die gemessene strecke ist derziet noch recht stark von der beleuchtung abhängig. so fährt er zb im schatten relativ genau seinen vorgegebenen winkel, jedoch bei zimmerbeleuchtung (energiesparlampe) fehlen immer einige grade. da muss ich wohl noch eine abschirmung der odometriesensoren basteln
wenn noch jemand irgendwelche verbesserungsvorschläge hat bitte bescheidsagen
Lesezeichen