PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kreis fahren



ehenkes
17.05.2007, 22:42
Ich habe versucht, die Funktion Go(...) auf eine Funktion Circle(...) umzuwandeln, funktioniert bisher allerdings nicht. ASURO dreht nur nach rechts am Punkt. Wo liegt der Fehler?



#include "myasuro.h" // #define MY_GO_CORRECTIVE_ACTION 15 // siehe unten
#include "asuro.h" // dort sind LEFT und RIGHT festgelegt

void Circle (int distance, int speed, int diameter, int direction)
{
const float HALFWidth_ASURO = 51.5; // Halber Radabstand des ASURO
float outer_diameter = (float) diameter + HALFWidth_ASURO;
float factor = outer_diameter / (float) diameter;

uint32_t enc_count;
int tot_count = 0;
float diff = 0;
int l_speed = speed, r_speed = speed;

// calculation tics/mm
enc_count=abs(distance)*10000L;
enc_count/=MY_GO_ENC_COUNT_VALUE;
EncoderSet(0,0); // reset encoder

MotorSpeed(l_speed,r_speed);
if (distance<0) MotorDir(RWD,RWD);
else MotorDir(FWD,FWD);

while (tot_count<enc_count)
{
if(direction==RIGHT) // Rechtskreis
{
tot_count += encoder[LEFT]/factor;
diff = (float) encoder[LEFT]/factor - (float) encoder[RIGHT]*factor;
}
if(direction==LEFT) // Linkskreis
{
tot_count += encoder[RIGHT]/factor;
diff = (float) encoder[RIGHT]/factor - (float) encoder[LEFT]*factor;
}

if (diff > 0)
{ //Left faster than right
if ((l_speed > speed) || (r_speed > 244)) l_speed -= MY_GO_CORRECTIVE_ACTION;
else r_speed += MY_GO_CORRECTIVE_ACTION;
}
if (diff < 0)
{ //Right faster than left
if ((r_speed > speed) || (l_speed > 244)) r_speed -= MY_GO_CORRECTIVE_ACTION;
else l_speed += MY_GO_CORRECTIVE_ACTION;
}
EncoderSet(0,0); // reset encoder
MotorSpeed(l_speed,r_speed);
Msleep(1);
}
MotorDir(BREAK,BREAK);
Msleep(200);
}

int main()
{
Init();
EncoderInit();
StatusLED (YELLOW);

Circle(5000,200,700,LEFT);

StatusLED (GREEN);

while (1);
return 0;
}

damaltor
18.05.2007, 13:44
hast du irgedwo RIGHT und LEFT definiert?

EDH
18.05.2007, 14:39
die sind irgendwo in der asruo.h definiert (war zumindest früher so ^^)

wie schauts mit MY_GO_CORRECTIVE_ACTION aus?

ich hab mal bei mir verschieden werte eingesetzt:

bei 1 fährt er eine gerade strekce auf und ab und dreht an den endenimmer.
bei 2 wird das ganze 3 eckig, ab 20 macht er gar nichts mehr.

aber mit nem wert von 15 gehts eingetlich einigermaßen.

edit:

hier maln video
(habs mit der handykamera gemacht.
>>> der player hier <<< (http://www.reganam.com/3gp-player-de.htm) sollte des aber eigneltich abspielen können)

ehenkes
18.05.2007, 16:50
Danke für den Test, sieht richtig gut aus! Die Konstante MY_GO_CORRECTIVE_ACTION habe ich in myasuro.h eingeführt anstelle des fixen Wertes 10 in Go(...) und Turn(...). LEFT und RIGHT sind in asuro.h festgelegt. Ich hatte den Wert 3 eingestellt für MY_GO_CORRECTIVE_ACTION, das war offenbar kein brauchbarer Wert. Vielleicht sollte man aus den Parametern der Funktion Circle einen optimalen Wert für die Geschwindigkeitskorrektur ableiten. Zusätzlich hatte ich Probleme mit der Hell-Dunkel-Erkennung des Odometriesystems.

ehenkes
18.05.2007, 17:32
Man könnte das Thema auch über eine Polygon-Funktion mit ganz vielen Vertices angehen. Ich habe mal etwas entwickelt:


#include "myasuro.h" /* #define MY_GO_CORRECTIVE_ACTION 3 */
#include "asuro.h"

void GoP (int distance,int speed)
{
uint32_t enc_count;
int tot_count = 0;
int diff = 0;
int l_speed = speed, r_speed = speed;

// calculation tics/mm
enc_count=abs(distance)*10000L;
enc_count/=MY_GO_ENC_COUNT_VALUE;
EncoderSet(0,0); // reset encoder

MotorSpeed(l_speed,r_speed);
if (distance<0) MotorDir(RWD,RWD);
else MotorDir(FWD,FWD);

while (tot_count<enc_count)
{
tot_count += encoder[RIGHT]; //im Original LEFT ehenkes
diff = encoder[LEFT] - encoder[RIGHT];
if (diff > 0)
{ //Left faster than right
if ((l_speed > speed) || (r_speed > 244)) l_speed -= MY_GO_CORRECTIVE_ACTION;
else r_speed += MY_GO_CORRECTIVE_ACTION;
}
if (diff < 0)
{ //Right faster than left
if ((r_speed > speed) || (l_speed > 244)) r_speed -= MY_GO_CORRECTIVE_ACTION;
else l_speed += MY_GO_CORRECTIVE_ACTION;
}
EncoderSet(0,0); // reset encoder
MotorSpeed(l_speed,r_speed);
}
}

void TurnP (int degree,int speed)
{
long enc_count;
enc_count=abs(degree)*MY_TURN_ENC_COUNT_VALUE;
enc_count /= 360L;

int tot_count = 0;
int diff = 0;
int l_speed = speed, r_speed = speed;

EncoderSet(0,0); // reset encoder

MotorSpeed(l_speed,r_speed);
if (degree<0) MotorDir(RWD,FWD);
else MotorDir(FWD,RWD);

while (tot_count<enc_count)
{
tot_count += encoder[LEFT];
diff = encoder[LEFT] - encoder[RIGHT];
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;
}
EncoderSet(0,0); // reset encoder
MotorSpeed(l_speed,r_speed);
}
}



void RegularPolygon (int NumberVertices, int LengthSide, int speed, int direction)
{
int i;
for(i=0;i<NumberVertices;++i)
{
GoP (LengthSide,speed);
if (direction==RIGHT)
TurnP ( 360L/NumberVertices,speed);
else
TurnP (-360L/NumberVertices,speed);
}
MotorSpeed(0,0);
}

int main(void)
{
Init();
EncoderInit();
StatusLED (YELLOW);

RegularPolygon(6,150,175,LEFT);

StatusLED (GREEN);

while (1);
return 0;
}