1 Replies - 483 Views - Last Post: 24 September 2010 - 12:11 AM Rate Topic: -----

#1 Fretwise  Icon User is offline

  • New D.I.C Head

Reputation: 6
  • View blog
  • Posts: 35
  • Joined: 15-February 09

Problem: Stack overflow correcting in C

Posted 23 September 2010 - 03:05 PM

I am currently programing a robot via handy board which handles a considerably smaller bit memory. I have it currently set up to detect if the robot is straight when crossing a line. The function checks to see which sensor is triggered first then corrects accordingly. The problem is if the recursion is called more than 25 times it will stack overflow. There is often cases where I quite possibly need to check 100+ times. I have probably a terrible way to fix it, but it works. I would like a proper way to do it.

Current Code:

//Aligns the car by backing up and slightly adjusting left and right.

void align(int left, int right, int checks,)
{   
    //backs up slightly.
    
    motor(0,-20);
    motor(1,23);
    sleep(0.25);
    
    //if left sensor is hit first, then prints the adjustment
    //steps back then adjusts, recalls the function check with 
    //an increased value. This is to prevent calling the function
    //twice in a row with hard braking.
    
    if (left > right)
      {
        printf("Adj: Left = %d\n", left);
        stepback();
        adjleft();
        check(ColorA, checks+1);
    }
    
    //does the same except calls the right adjust if the right sensor
    //is triggered.
    
    if (right > left)
      {
        printf("Adj: Right = %d\n", right);
        stepback();
        adjright();
        check(ColorA, checks+1);
    }
    
    //off
    
    ao();
}

//function does all the sensor checking and sends it to the
//align function.

void check(int Color, int AttemptedChecks)
{   
        //restarts the check each time the function is called
        
        int left = 0;
        int right = 0;
        
        //moves forward until triggered.
        
        forward();
        
    /*
    Note: due to a inequality in the two sensors they check for
    different values, which have been adjusted accordingly. The reason
    for both ColorMod and ColorAdj is for a tighter recognition when box
    checking.
    */
        
        while (analog(4) < ColorAdj || analog(3) < Color)
          {
            if (analog(3) >= Color)
              {
                right++;
                break;
            }
            
            else if (analog(4) >= ColorMod)
              {
                left++;
                break;
            }
            
            //very important here, without this if the analog(4) sensor is between
            //ColorMod and ColorAdj then it will go left, thus making the roboto go left
            //when getting close to the mark instead of going right OR left depending on 
            //whats needed.
            
            else if (analog(4) < ColorMod && analog(4) >=ColorAdj && analog(3) > Color)
              {
                right++;
                break;
            }
        }
        
        //if the car is not straight from the start it will
        //brake and call the align function. Here is were the
        //function arguments determine what speed to slow down.
        
        if (left !=0 || right != 0)
          {
            if (AttemptedChecks == 0)
              {
                brake();
            }
            else if (AttemptedChecks !=0)
              {
                softbrake();
            }
            ao();
            sleep(1.5);
            
            //recalls function if not straight
            
            align(left, right, AttemptedChecks);
        }
        
        //if 100% then low brakes and displays straight.
        
        if (right == 0 && left == 0)
          {
            brake();
            
            printf("Straight!\n");
            ao();
            sleep(1.5);
        }
    }
}



Here is the fix:

//Aligns the car by backing up and slightly adjusting left and right.

void align(int left, int right, int checks, int *count)
{   
    //backs up slightly.
    
    motor(0,-20);
    motor(1,23);
    sleep(0.25);
    
    //if left sensor is hit first, then prints the adjustment
    //steps back then adjusts, recalls the function check with 
    //an increased value. This is to prevent calling the function
    //twice in a row with hard braking.
    
    if (left > right)
      {
        printf("Adj: Left = %d\n", left);
        stepback();
        adjleft();
        check(ColorA, checks+1, count);
    }
    
    //does the same except calls the right adjust if the right sensor
    //is triggered.
    
    if (right > left)
      {
        printf("Adj: Right = %d\n", right);
        stepback();
        adjright();
        check(ColorA, checks+1, count);
    }
    
    //off
    
    ao();
}

//function does all the sensor checking and sends it to the
//align function.

void check(int Color, int AttemptedChecks, int *Count)
{   
    
    //while loop to prevent stack overflow, does not let
    //the function get recalled more than 5 times.
    
    while (*Count < 5)
      {
        
        //restarts the check each time the function is called
        
        int left = 0;
        int right = 0;
        
        //moves forward until triggered.
        
        forward();
        
        /*
    Note: due to a inequality in the two sensors they check for
    different values, which have been adjusted accordingly. The reason
    for both ColorMod and ColorAdj is for a tighter recognition when box
    checking.
    */
        
        while (analog(4) < ColorAdj || analog(3) < Color)
          {
            if (analog(3) >= Color)
              {
                right++;
                break;
            }
            
            else if (analog(4) >= ColorMod)
              {
                left++;
                break;
            }
            
            //very important here, without this if the analog(4) sensor is between
            //ColorMod and ColorAdj then it will go left, thus making the roboto go left
            //when getting close to the mark instead of going right OR left depending on 
            //whats needed.
            
            else if (analog(4) < ColorMod && analog(4) >=ColorAdj && analog(3) > Color)
              {
                right++;
                break;
            }
        }
        
        //if the car is not straight from the start it will
        //brake and call the align function. Here is were the
        //function arguments determine what speed to slow down.
        
        if (left !=0 || right != 0)
          {
            if (AttemptedChecks == 0)
              {
                brake();
            }
            else if (AttemptedChecks !=0)
              {
                softbrake();
            }
            ao();
            sleep(1.5);
            
            
            //incriments pointer  
            
            *Count++;
            
            //recalls function if not straight
            
            align(left, right, AttemptedChecks, Count);
        }
        
        //if 100% then low brakes and displays straight.
        
        if (right == 0 && left == 0)
          {
            brake();
            
            printf("Straight!\n");
            ao();
            sleep(1.5);
            *Count = 999;
        }
    }
}



calling the function with this, instead of check();

//this function fixes the runtime error achieved when the
//check function is run over 25 times without a break
//this recalls the function in order to dump it out of memory
//after 10 calls so it will not stack overflow.

void check_fix(int color, int brake)
{
    int count;
    
    //sentinal value
    
    while (count != 999)
      {
        count = 0;
        check(ColorA, 1, &count);
    }
}



In case you are not wanting to read through the fix to figure out what I did. I pretty much added a While-Loop that will recall the function after every X amount of attempts to keep it from getting called to many times within itself. Any ideas on the best way to tackle this instead of what I did? Thanks in advance, and if you need more information let me know :)

Is This A Good Question/Topic? 0
  • +

Replies To: Problem: Stack overflow correcting in C

#2 Salem_c  Icon User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 1675
  • View blog
  • Posts: 3,169
  • Joined: 30-May 10

Re: Problem: Stack overflow correcting in C

Posted 24 September 2010 - 12:11 AM

So don't use recursion then!

Create a struct containing all the information both functions need, then do something like
struct foo s;
// initialise with all the params for sensors etc
while ( detectGoal(&s) ) {  // did we get to the end?
  move(&s);  // does a small move
  check(&s); // see what happened
  align(&s); // adjust
}


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1