// Programed by Jung, HyunRyong
// File name : line-follow.c
// Date :  2002. 12. 02

#include "eyebot.h"
#include <stdlib.h>

// center point of x axis
#define CEN_POINT 41

// global variables
colimage	g_matrix;      // keep color image
VWHandle 	vw_handle;     // handle of the motors
image		g_grey;        // keep binary image

// declare functions
void BinaryImage(colimage img, int threshold);
void Steer(int center, BOOL turn);


void BinaryImage(colimage img, int threshold)
{
   int i, j;
   int sum = 0, x_spos = 0, x_lpos = 0, c_point;
   int count = 0, t_count = 0;
   int start = 31;

   for(j = 0; j < imagerows; j++)
       for(i = 0; i < imagecolumns; i++)
       {
          // make grey image           
          sum = (img[j][i][0] + img[j][i][1] + img[j][i][2]) / 3;
		
          if(j == start + 1 && count == 0)
             start++;

          // make binary image
          if(sum > threshold)
          {
 	     g_grey[j][i] = 0;
             t_count++;
             
             if(j == start && count == 0)
             {
                x_spos = i;
                count++;
             }
             else if(j == start && count != 0)
             {
                x_lpos = i;
                count++; 
             }
          }
          else
             g_grey[j][i] = 255;
       }

   // display the binary image
   LCDPutGraphic(&g_grey);

   // find the center point
   if(count >= 2)
      c_point = (x_spos + x_lpos) * 0.5;
   else
      c_point = 41; 

   LCDSetPos(0, 0);
   LCDPrintf("%3d %3d %3d", x_spos, x_lpos, c_point);

   // cross hair
   LCDLine(c_point, start + 2, c_point, start - 2, 2);
   LCDLine(c_point - 2, start, c_point + 2, start, 2); 

   // if do not detect lane, turn around
   if(t_count == 0)
      Steer(c_point, 1);
   else
      Steer(c_point, 0);
}


void Steer(int center, BOOL turn)
{
   int gap;
 
   gap = CEN_POINT - center;
   
   if(gap > CEN_POINT)
      gap = CEN_POINT;
   if(gap < -CEN_POINT)
      gap = -CEN_POINT;
   
   LCDSetPos(2, 10);
   LCDPrintf("%3d", gap);

   // turn around
   if(turn)
   {
      LCDSetPos(3, 10);
      LCDPrintf("Back ");

        VWDriveStraight(vw_handle, 0.06, 0.3);
	VWDriveWait(vw_handle);

	VWSetSpeed(vw_handle, 0,0);
	OSWait(10);

        VWDriveStraight(vw_handle, -0.04, 0.3);
	VWDriveWait(vw_handle);

	VWSetSpeed(vw_handle, 0,0);
	OSWait(10);

      VWDriveTurn(vw_handle, 3.14, 1.2);
      VWDriveWait(vw_handle);
      OSWait(10);
   }
   else
   {
      // turn left
      if(gap > 5)
      {
          gap *= 0.073;
          VWSetSpeed(vw_handle, 0.05, 0.18 * gap);
          LCDSetPos(3, 10);
          LCDPrintf("Left ");
      }
      // turn right
      else if(gap < -5)
      { 
          gap *= 0.073;
          VWSetSpeed(vw_handle, 0.05, 0.18 * gap);
          LCDSetPos(3, 10);
          LCDPrintf("Right");
      }
      // go straight
      else
      {
          VWSetSpeed(vw_handle, 0.05, 0.00);
          LCDSetPos(3, 10);
          LCDPrintf("Go     ");
      }
   }
}


int main()
{
   int value;

   value = CAMInit(NORMAL);

   if(value == 255)
      LCDPrintf("Error in init LCD\n");
   else
   {
      // initialize the motors
      vw_handle = VWInit(VW_DRIVE, 1); 
      VWStartControl(vw_handle, 7.0, 0.3, 7.0, 0.1);

      LCDMenu("", "", "", "Exit");

      while(KEYRead() != KEY4)
      {
         // get a image from camera
         CAMGetColFrame(&g_matrix, FALSE);
         BinaryImage(g_matrix, 180);
      }
      VWStopControl(vw_handle);
      VWRelease(vw_handle);
   }
   return 0;
}


