Added program for mark detection (Cross line, Left half line and Right half line).

Dependencies:   GR-PEACH_video mbed

Fork of TraceMark_Program_60fps by Micon Car Rally

Revision:
2:af4db183ee76
Parent:
1:4a94c87a7d04
--- a/main.cpp	Tue Jan 10 04:59:48 2017 +0000
+++ b/main.cpp	Fri Mar 17 03:53:01 2017 +0000
@@ -2,17 +2,17 @@
 //Supported MCU:   RZ/A1H
 //File Contents:   Trace Program by Image Processing
 //                                 (GR-PEACH version on the Micon Car)
-//Version number:  Ver.1.01
-//Date:            2017.01.10
+//Version number:  Ver.2.00
+//Date:            2017.03.17
 //Copyright:       Renesas Electronics Corporation
 //                 Hitachi Document Solutions Co., Ltd.
 //------------------------------------------------------------------//
-
+ 
 //This program supports the following boards:
 //* GR-PEACH(E version)
 //* Motor drive board Ver.5
 //* Camera module (SC-310)
-
+ 
 //Include
 //------------------------------------------------------------------//
 #include "mbed.h"
@@ -52,6 +52,9 @@
 #define     MOTOR_START         0x04
 #define     MOTOR_STOP          0x05
 #define     MARK_T              0x06
+#define     MARK_C              0x07
+#define     MARK_R              0x08
+#define     MARK_L              0x09
  
 //Define(NTSC-Video)
 //------------------------------------------------------------------//
@@ -107,6 +110,7 @@
 void led_out(int led);
 unsigned int pushsw_get( void );
 void motor( int accele_l, int accele_r );
+void motor2( int accele_l, int accele_r );
 void handle( int angle );
 int diff( int pwm );
  
@@ -128,8 +132,16 @@
 double Standard_Deviation( unsigned char *data, double *Devi, int items );
 double Covariance( double *Devi_A, double *Devi_B, int items );
 int Judgement_ImageMatching( double covari, double SDevi_A, double SDevi_B );
+
 void MarkDetect_process_T( void );
+void MarkDetect_process_C( void );
+void MarkDetect_process_R( void );
+void MarkDetect_process_L( void );
+
 int MarkCheck_Triangle( int percentage );
+int MarkCheck_Crossline( int percentage );
+int MarkCheck_Rightline( int percentage );
+int MarkCheck_Leftline( int percentage );
 
 //Prototype(Display Debug)
 //------------------------------------------------------------------//
@@ -162,18 +174,32 @@
 unsigned char   TempBinary_Triangle[15] = {0,1,1,1,0,
                                            0,0,1,0,0,
                                            0,0,0,0,0};
-
-double          NowDevi[15];
-unsigned char   NowImageBinary[15];
+double          TempDevi_Crossline[28];
+unsigned char   TempBinary_Crossline[28] = {0,0,0,0,0,1,1,1,1,0,0,0,0,0,
+                                            1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+double          TempDevi_Rightline[28];
+unsigned char   TempBinary_Rightline[28] = {0,0,0,0,0,1,1,1,1,0,0,0,0,0,
+                                            0,0,0,0,0,0,1,1,1,1,1,1,1,1};
+double          TempDevi_Leftline[28];
+unsigned char   TempBinary_Leftline[28]  = {0,0,0,0,0,1,1,1,1,0,0,0,0,0,
+                                            1,1,1,1,1,1,1,1,0,0,0,0,0,0};
+double          NowDevi[30];
+unsigned char   NowImageBinary[30];
 
 volatile double retDevi_Triangle;
+volatile double retDevi_Crossline;
+volatile double retDevi_Rightline;
+volatile double retDevi_Leftline;
 
 volatile double retDevi;
 volatile double retCovari;
 volatile int    retJudgeIM;
-volatile int    retJudgeIM_Max[1];
+volatile int    retJudgeIM_Max[4];
 
 int             Xt, Yt;
+int             Xc, Yc;
+int             Xr, Yr;
+int             Xl, Yl;
 
 //Globle variable for led fanction
 //------------------------------------------------------------------//
@@ -186,7 +212,10 @@
                                   LED_BLUE,    50,    50,   /* DEBUG  */
                                   LED_GREEN,    1,     0,   /* MOTOR_START */
                                   LED_RED,      1,     0,   /* MOTOR_STOP */
-                                  LED_WHITE,  500,   500};  /* MARK_T */
+                                  LED_WHITE,  500,   500,   /* MARK_T */
+                                  LED_YELLOW, 500,   500,   /* MARK_C */
+                                  LED_PURPLE, 500,   500,   /* MARK_R */
+                                  LED_SKYBLUE,500,   500};  /* MARK_L */
 
 //Globle variable for Trace program
 //------------------------------------------------------------------//
@@ -195,6 +224,8 @@
 volatile int            pattern;        /* Pattern numbers          */
 volatile int            handle_buff;
 
+volatile unsigned long  main_cnt = 0;           /* Used by timer function   */
+
 const int revolution_difference[] = {
     100, 98, 97, 95, 93, 
     92, 90, 88, 87, 85, 
@@ -306,6 +337,9 @@
 
     /* Initialize Mark detection */
     retDevi_Triangle  = Standard_Deviation( TempBinary_Triangle, TempDevi_Triangle, 15 );
+    retDevi_Crossline = Standard_Deviation( TempBinary_Crossline, TempDevi_Crossline, 28 );
+    retDevi_Rightline = Standard_Deviation( TempBinary_Rightline, TempDevi_Rightline, 28 );
+    retDevi_Leftline  = Standard_Deviation( TempBinary_Leftline, TempDevi_Leftline, 28 );
 
     if( user_button_get() ) {
         wait(0.1);
@@ -314,16 +348,15 @@
         wait(0.5);
         pc.printf( "Please push the SW ( on the Motor drive board )\n\r" );
         pc.printf( "\n\r" );
-        while( !user_button_get() );
+        while( !pushsw_get() );
         while( 1 ){
             ImageData_Serial_Out2( ImageBinary, 20 );
         }
     }
-
     led_m_set( RUN );
  
     while( 1 ) {
- 
+
     switch( pattern ) {
     /*****************************************************************
     About patern
@@ -350,7 +383,7 @@
             cnt1 = 0;
         }
         break;
- 
+
     case 11:
         /* normal trace */
         if( MarkCheck_Triangle( 90 ) ) {
@@ -358,6 +391,21 @@
             pattern = 91;
             break;
         }
+        if( MarkCheck_Crossline( 90 ) ) {  /* Cross line check     */
+            led_m_set( MARK_C );
+            pattern = 21;
+            break;
+        }
+        if( MarkCheck_Rightline( 90 ) ) {   /* Right half line detection check */
+            led_m_set( MARK_R );
+            pattern = 51;
+            break;
+        }
+        if( MarkCheck_Leftline( 90 ) ) {    /* Left half line detection check */
+            led_m_set( MARK_L );
+            pattern = 61;
+            break;
+        }
         switch( (digital_sensor()&0x0f) ) {
             case 0x00:
                 handle( 0 );
@@ -393,7 +441,7 @@
                 break;
         }
         break;
-
+    
     case 12:
         /* Left side */
         if( (digital_sensor()&0x02) == 0x02 ) {
@@ -415,7 +463,7 @@
                 break;
         }
         break;
-
+ 
     case 13:
         /* right side */
         if( (digital_sensor()&0x04) == 0x04 ) {
@@ -437,8 +485,255 @@
         }
         break;
 
+    case 21:
+        /* Processing at 1st cross line */
+        led_out( 0x3 );
+        handle( 0 );
+        motor2( 0 ,0 );
+        pattern = 22;
+        cnt1 = 0;
+        break;
+
+    case 22:
+        /* Read but ignore 2nd line */
+        if( cnt1 > 100 ) {
+            pattern = 23;
+            cnt1 = 0;
+        }
+        break;
+
+    case 23:
+        /* Trace, crank detection after cross line */
+        if( (digital_sensor()&0x0c) == 0x0c) {
+            /* Left crank determined -> to left crank clearing processing */
+            led_out( 0x1 );
+            pattern = 31;
+            cnt1 = 0;
+            break;
+        }
+        if( (digital_sensor()&0x03) == 0x03 ) {
+            /* Right crank determined -> to right crank clearing processing */ 
+            led_out( 0x2 );
+            pattern = 41;
+            cnt1 = 0;
+            break;
+        }
+        switch( (digital_sensor()&0x0f) ) {
+            case 0x00:
+                /* Center -> straight */
+                handle( 0 );
+                motor2( 27 ,27 );
+                break;
+            case 0x02:
+                /* Left of center -> turn to right */
+                handle( 4 );
+                motor2( 27 ,diff(27) );
+                break;
+            case 0x04:
+                /* Right of center -> turn to left */
+                handle( -4 );  
+                motor2( diff(27) ,27 );
+                break;
+            default:
+                break;
+        }
+        break;
+ 
+    case 31:
+        if( (digital_sensor()&0x0f) == 0x00 ) {
+            handle( -40 );
+            motor2( diff(25) ,45 );
+            pattern = 32;
+            cnt1 = 0;
+        }
+        break;
+
+    case 32:
+        /* Left crank clearing processing - wait until stable */
+        if( cnt1 > 300 ) {
+            pattern = 33;
+            cnt1 = 0;
+        }
+        break;
+
+    case 33:
+        /* Left crank clearing processing - check end of turn */
+        if( (digital_sensor()&0x04) == 0x04 ) {
+            led_out( 0x0 );
+            led_m_set( RUN );
+            pattern = 11;
+            cnt1 = 0;
+        }
+        break;
+
+    case 41:
+        if( (digital_sensor()&0x0f) == 0x00 ) {
+            handle( 41 );
+            motor2( 50 ,diff(25) );
+            pattern = 42;
+            cnt1 = 0;
+        }
+        break;
+
+    case 42:
+        /* Right crank clearing processing - wait until stable */
+        if( cnt1 > 300 ) {
+            pattern = 43;
+            cnt1 = 0;
+        }
+        break;
+ 
+    case 43:
+        /* Right crank clearing processing - check end of turn */
+        if( (digital_sensor()&0x02) == 0x02 ) {
+            led_out( 0x0 );
+            led_m_set( RUN );
+            pattern = 11;
+            cnt1 = 0;
+        }
+        break;
+
+    case 51:
+        /* Processing at 1st right half line detection */
+        led_out( 0x2 );
+        handle( 0 );
+        motor2( 0 ,0 );
+        pattern = 52;
+        cnt1 = 0;
+        break;
+ 
+    case 52:
+        /* Read but ignore 2nd time */
+        if( cnt1 > 100 ) {
+            pattern = 53;
+            cnt1 = 0;
+            break;
+        }
+        if( MarkCheck_Crossline( 90 ) ) {  /* Cross line check     */
+            led_m_set( MARK_C );
+            pattern = 21;
+            break;
+        }
+        break;
+
+    case 53:
+        /* Trace, lane change after right half line detection */
+        if( (digital_sensor()&0x1f) == 0x00 ) {
+            handle( 22 );
+            motor2( 35 ,diff(25) );
+            pattern = 54;
+            cnt1 = 0;
+            break;
+        }
+        switch( (digital_sensor()&0x0f) ) {
+            case 0x00:
+                /* Center -> straight */
+                handle( 0 );
+                motor2( 30 ,30 );
+                break;
+            case 0x02:
+                /* Left of center -> turn to right */
+                handle( 4 );
+                motor2( 30 ,diff(30) );
+                break;
+            case 0x04:
+                /* Right of center -> turn to left */
+                handle( -4 );  
+                motor2( diff(30) ,30 );
+                break;
+            default:
+                break;
+        }
+        break;
+ 
+    case 54:
+        if( cnt1 > 500 ){
+            pattern = 55;
+            cnt1 = 0;
+        }
+        break;
+ 
+    case 55:
+        /* Right lane change end check */
+        if( (digital_sensor()&0x04) == 0x04 ) {
+            led_out( 0x0 );
+            led_m_set( RUN );
+            pattern = 11;
+            cnt1 = 0;
+        }
+        break;
+ 
+    case 61:
+        /* Processing at 1st left half line detection */
+        led_out( 0x1 );
+        handle( 0 );
+        motor2( 0 ,0 );
+        pattern = 62;
+        cnt1 = 0;
+        break;
+ 
+    case 62:
+        /* Read but ignore 2nd time */
+        if( cnt1 > 100 ) {
+            pattern = 63;
+            cnt1 = 0;
+            break;
+        }
+        if( MarkCheck_Crossline( 90 ) ) {  /* Cross line check     */
+            led_m_set( MARK_C );
+            pattern = 21;
+            break;
+        }
+        break;
+ 
+    case 63:
+        /* Trace, lane change after left half line detection */
+        if( (digital_sensor()&0x1f) == 0x00 ) {
+            handle( -22 );
+            motor2( diff(25) ,35 );
+            pattern = 64;
+            cnt1 = 0;
+            break;
+        }
+        switch( (digital_sensor()&0x0f) ) {
+            case 0x00:
+                /* Center -> straight */
+                handle( 0 );
+                motor2( 35 ,35 );
+                break;
+            case 0x02:
+                /* Left of center -> turn to right */
+                handle( 4 );
+                motor2( 35 ,diff(35) );
+                break;
+            case 0x04:
+                /* Right of center -> turn to left */
+                handle( -4 );
+                motor2( diff(35) ,35 );
+                break;
+            default:
+                break;
+        }
+        break;
+ 
+    case 64:
+        if( cnt1 > 500 ){
+            pattern = 65;
+            cnt1 = 0;
+        }
+        break;
+ 
+    case 65:
+        /* Left lane change end check */
+        if( (digital_sensor()&0x02) == 0x02 ) {
+            led_out( 0x0 );
+            led_m_set( RUN );
+            pattern = 11;
+            cnt1 = 0;
+        }
+        break;
+
     case 91:
-        /* Stop */
         handle( 0 );
         motor( 0, 0 );
         break;
@@ -541,6 +836,7 @@
     /* top or bottom (Change) */
     if      ( vfield_count2 == 0 )  vfield_count2 = 1;
     else if ( vfield_count2 == 1 )  vfield_count2 = 0;
+    led_m_user( vfield_count2 );
 }
  
 //******************************************************************//
@@ -587,17 +883,15 @@
 void intTimer( void )
 {
     static int  counter = 0;
- 
+
     cnt0++;
     cnt1++;
  
     /* field check */
-    if( vfield_count2 != vfield_count2_buff ) {
+    if( vfield_count2 == vfield_count2_buff ) {
         vfield_count2_buff = vfield_count2;
-        counter = 0;
     }
-    /* Top field / bottom field */
-    led_m_user( vfield_count2 );
+   /* Top field / bottom field */
     switch( counter++ ) {
     case 0:
         Image_Extraction( write_buff_addr, ImageData_A, vfield_count2 );
@@ -622,10 +916,25 @@
         //MarkCheck_Triangle
         MarkDetect_process_T();
         break;
+    case 7:
+        //MarkCheck_Crossline
+        MarkDetect_process_C();
+        break;
+    case 8:
+        //MarkCheck_Rightline
+        MarkDetect_process_R();
+        break;
+    case 9:
+        //MarkCheck_Leftline
+        MarkDetect_process_L();
+        break;
+    case 15:
+        counter = 0;
+        break;
     default:
         break;
+
     }
-
     /* LED processing */
     led_m_process();
 }
@@ -727,7 +1036,36 @@
         MTU2TGRD_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * ( -accele_r ) / 100;
     }
 }
+
+//motor speed control(PWM)
+//Arguments: motor:-100 to 100
+//Here, 0 is stop, 100 is forward, -100 is reverse
+//------------------------------------------------------------------//
+void motor2( int accele_l, int accele_r )
+{
+    /* Left Motor Control */
+    if( accele_l >= 0 ) {
+        /* forward */
+        Left_motor_signal = 0;
+        MTU2TGRC_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * accele_l / 100;
+    } else {
+        /* reverse */
+        Left_motor_signal = 1;
+        MTU2TGRC_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * ( -accele_l ) / 100;
+    }
  
+    /* Right Motor Control */
+    if( accele_r >= 0 ) {
+        /* forward */
+        Right_motor_signal = 0;
+        MTU2TGRD_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * accele_r / 100;
+    } else {
+        /* reverse */
+        Right_motor_signal = 1;
+        MTU2TGRD_4 = (long)( MOTOR_PWM_CYCLE - 1 ) * ( -accele_r ) / 100;
+    }
+}
+
 //handle Function
 //------------------------------------------------------------------//
 void handle( int angle )
@@ -1054,6 +1392,75 @@
     }
 }
 
+// MarkDetect_process_C
+//------------------------------------------------------------------//
+void MarkDetect_process_C( void )
+{
+    int  x, y;
+
+    retJudgeIM_Max[1] = 0;
+    for( y = 0; y <= 13; y++ ) {
+        for( x = 0; x <= 6; x++ ) {
+            Image_part_Extraction( ImageBinary, 20, x, y, NowImageBinary, 14, 2 );
+            retDevi    = Standard_Deviation( NowImageBinary, NowDevi, 28 );
+            retCovari  = Covariance( TempDevi_Crossline, NowDevi, 28 );
+            retJudgeIM = 0;
+            retJudgeIM = Judgement_ImageMatching( retCovari, retDevi_Crossline, retDevi );
+            if( 100 >= retJudgeIM && retJudgeIM > retJudgeIM_Max[1] ) {
+                Xc = x;
+                Yc = y;
+                retJudgeIM_Max[1] = retJudgeIM;
+            }
+        }
+    }
+}
+
+// MarkDetect_process_R
+//------------------------------------------------------------------//
+void MarkDetect_process_R( void )
+{
+    int  x, y;
+
+    retJudgeIM_Max[2] = 0;
+    for( y = 0; y <= 13; y++ ) {
+        for( x = 0; x <= 6; x++ ) {
+            Image_part_Extraction( ImageBinary, 20, x, y, NowImageBinary, 14, 2 );
+            retDevi    = Standard_Deviation( NowImageBinary, NowDevi, 28 );
+            retCovari  = Covariance( TempDevi_Rightline, NowDevi, 28 );
+            retJudgeIM = 0;
+            retJudgeIM = Judgement_ImageMatching( retCovari, retDevi_Rightline, retDevi );
+            if( 100 >= retJudgeIM && retJudgeIM > retJudgeIM_Max[2] ) {
+                Xr = x;
+                Yr = y;
+                retJudgeIM_Max[2] = retJudgeIM;
+            }
+        }
+    }
+}
+
+// MarkDetect_process_L
+//------------------------------------------------------------------//
+void MarkDetect_process_L( void )
+{
+    int  x, y;
+
+    retJudgeIM_Max[3] = 0;
+    for( y = 0; y <= 13; y++ ) {
+        for( x = 0; x <= 6; x++ ) {
+            Image_part_Extraction( ImageBinary, 20, x, y, NowImageBinary, 14, 2 );
+            retDevi    = Standard_Deviation( NowImageBinary, NowDevi, 28 );
+            retCovari  = Covariance( TempDevi_Leftline, NowDevi, 28 );
+            retJudgeIM = 0;
+            retJudgeIM = Judgement_ImageMatching( retCovari, retDevi_Leftline, retDevi );
+            if( 100 >= retJudgeIM && retJudgeIM > retJudgeIM_Max[3] ) {
+                Xl = x;
+                Yl = y;
+                retJudgeIM_Max[3] = retJudgeIM;
+            }
+        }
+    }
+}
+
 // MarkCheck Triangle detection
 // Return values: 0: no triangle mark, 1: Triangle mark
 //------------------------------------------------------------------//
@@ -1069,6 +1476,51 @@
     return ret;
 }
 
+// Cross line detection processing
+// Return values: 0: no cross line, 1: cross line
+//------------------------------------------------------------------//
+int MarkCheck_Crossline( int percentage )
+{
+    int ret;
+
+    ret = 0;
+    if( retJudgeIM_Max[1] >= percentage ) {
+        ret = 1;
+    }
+
+    return ret;
+}
+
+// Right half line detection processing
+// Return values: 0: not detected, 1: detected
+//------------------------------------------------------------------//
+int MarkCheck_Rightline( int percentage )
+{
+    int ret;
+
+    ret = 0;
+    if( retJudgeIM_Max[2] >= percentage ) {
+        ret = 1;
+    }
+
+    return ret;
+}
+
+// Left half line detection processing
+// Return values: 0: not detected, 1: detected
+//------------------------------------------------------------------//
+int MarkCheck_Leftline( int percentage )
+{
+    int ret;
+
+    ret = 0;
+    if( retJudgeIM_Max[3] >= percentage ) {
+        ret = 1;
+    }
+
+    return ret;
+}
+
 //******************************************************************//
 // Debug functions
 //*******************************************************************/
@@ -1105,8 +1557,11 @@
     pc.printf( "\n\r" );
     pc.printf( "sensor_inp = 0x%02x\n\r", digital_sensor() );
     pc.printf( "T = %3d%% %01d X=%2d Y=%2d\n\r", retJudgeIM_Max[0], MarkCheck_Triangle( 90 ),  Xt, Yt );
+    pc.printf( "C = %3d%% %01d X=%2d Y=%2d\n\r", retJudgeIM_Max[1], MarkCheck_Crossline( 90 ), Xc, Yc );
+    pc.printf( "R = %3d%% %01d X=%2d Y=%2d\n\r", retJudgeIM_Max[2], MarkCheck_Rightline( 90 ), Xr, Yr );
+    pc.printf( "L = %3d%% %01d X=%2d Y=%2d\n\r", retJudgeIM_Max[3], MarkCheck_Leftline( 90 ),  Xl, Yl );
     pc.printf( "\n\r" );
-    Height += 4;
+    Height += 7;
 
     pc.printf( "\033[%dA" , Height );
 }