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