Adavnced Line following

I am trying to follow a line more effectively. It works right now but it makes a saw pattern and is almost never going straight. I would think that a P.I.D. loop would be the way to go, but to do this I need an analog line position as an input.

An analog line position is where the robot knows exactly where the line is and how much it needs to turn to get back on the line (a reading would range from -100 to +100, 0 would mean that the robot is centered on the line)

Verses a digital line position were the robot has only three possibilities, left, middle, right, (or 1,2,3) and is always over correcting itself. (this is the only thing I have ever seen used with a vex robot)

Any help you could offer would be very appreciated, Titan 103

Wow, it’s hard to keep up with you guys, you post all over the place. I recently made a demo for our sales guys using a two sensor PID that might be what you are looking for. It uses a fixed driving speed, that could use some love by incorporating the center sensor but, it should get you/others started.

Main function:


void main ( void )
{
      int speed; 
      int rotation; 
      int lineOneOut; 
      int lineTwoOut; 

      InitLineSensors ( ) ;
      PrintToScreen ( "Line1 %d | Line2 %d | Line3 %d\n",lineOneBias ,lineTwoBias ,lineThreeBias  ) ;
      while ( 1 )
      {
            lineOneOut =  (int)GetAnalogInput ( 1 ) - lineOneBias ;
            lineTwoOut = (int)GetAnalogInput ( 3 ) - lineThreeBias ;
            rotation =  (lineOneOut - lineTwoOut) / 20 ;
            //speed =  15 + (int)(GetAnalogInput ( 2 )- lineTwoBias) ;
            if ( rotation > 25 || rotation < -25 )
            {
                  speed =  0 ;
            }
            else
            {
                  speed =  30 ;
            }
            SetPWM ( 2 , ( rotation - speed) + 127 ) ;
            SetPWM ( 3 , (rotation + speed) +127 ) ;
            PrintToScreen ( "speed %d , rotation %d\n", speed, rotation ) ;
            Wait ( 10 ) ;
      }
}

Compute Line Sensor Bias


unsigned int lineSensorBias ( unsigned char sensor )
{
      unsigned long linesum = 0; 
      unsigned char i; 
      unsigned int bias; 

      for ( i = 0 ; i < BIASCALC ; i++ )
      {
            linesum += GetAnalogInput ( sensor ) ;
            Wait ( 1 ) ;
      }
      bias= linesum / BIASCALC ;
}

Init Line Sensor


void InitLineSensors ( void )
{
      Wait ( 2000 ) ;
      lineOneBias = lineSensorBias ( 1 ) ;
      lineTwoBias = lineSensorBias ( 2 ) ;
      lineThreeBias = lineSensorBias ( 3 ) ;
      Wait ( 1000 ) ;
}

**Notes: **
BAISCALC = 500
LineOneBias, LineTwoBias, LineThreeBias are Global Variables

this looks awesome! I’ve been working with a 1 sensor PD loop but 2 sensors would work even better I am sure.

I am wondering how to write the above code with Easy C V2. Are the second two blocks of text user functions? Would it be possible to make it all in one project?

Sorry for the delay, use user code blocks or just call the appropriate blocks that match the functions defined here. Some may require an additional step using an assignment. The only code that must used in a User Code block is the PrintToScreen because it has multiple variables. If you have trouble let me know.

Also, I’ve upgraded this code to 4 sensors and it scales nicely.
The change is adding the sensors and making the outside sensor worth 2x the value of the inside sensors. So, basically,
rotation = ((leftoutside2) + leftinside - rightinside + (rightoutside2)) / 20 ;

I got the 2 sensor setup to work very well. I liked that it had no saw pattern at all. What I did not like was that it needs to be going slowly in order to work right, but… oh well.
I will have to get some more sensors in order to try the 4 sensor code. Does this one work with a faster robot?

Thanks for the help Titan 103