SmartWheels self-driving race car. Designed for NXP Cup. Uses FRDM-KL25Z, area-scan camera, and simple image processing to detect and navigate any NXP spec track.

Dependencies:   TSI USBDevice mbed-dev

Fork of SmartWheels by haofan Zheng

Revision:
100:ffbeefc9e218
Parent:
99:c6665262fd3d
--- a/Hardwares/ArduCAM.cpp	Thu Apr 20 16:23:19 2017 +0000
+++ b/Hardwares/ArduCAM.cpp	Thu Apr 20 21:04:10 2017 +0000
@@ -1,6 +1,6 @@
 #include "ArduCAM.h"
 
-//#define SW_DEBUG
+#define SW_DEBUG
 #include "GlobalVariable.h"
 #include "SWCommon.h"
 
@@ -25,16 +25,18 @@
 
 const static uint8_t CAM_BLK_CAL_LEFT  = ((RESOLUTION_WIDTH / 2) - 1);
 const static uint8_t CAM_BLK_CAL_RIGHT = ((RESOLUTION_WIDTH / 2) + 1);
-const static uint8_t TERMINATE_WIDTH = static_cast<uint8_t>(RESOLUTION_WIDTH * 0.28f);
+const static uint8_t TERMINATE_WIDTH = static_cast<uint8_t>(RESOLUTION_WIDTH * 0.29f);
 
 static DigitalOut cam_cs(PIN_ACC_CS, 1);
 
 static uint8_t temp_mid_pos = RESOLUTION_WIDTH / 2;
 static uint8_t black_calibrate = 70;
-static volatile uint8_t centerLine[CAM_ROI_UPPER_LIMIT * 2];
-static volatile uint8_t is_encounter_terminate = 0;
-//static volatile uint8_t is_border_find = BOTH_NOT_FOUND;
-static volatile uint8_t is_intersection_detected = 0;
+static uint8_t centerLine[CAM_ROI_UPPER_LIMIT * 2];
+static uint8_t leftLine[CAM_ROI_UPPER_LIMIT];
+static uint8_t rightLine[CAM_ROI_UPPER_LIMIT];
+static const uint8_t lineArrayEnd = CAM_ROI_UPPER_LIMIT - 1;
+static uint8_t is_encounter_terminate = 0;
+static uint8_t intersection_info = INTERSECTION_NULL;
 
 void cal_black_calibrate();
 
@@ -220,14 +222,21 @@
 
 }
 
-volatile const uint8_t* ardu_cam_get_center_array()
+ const uint8_t* ardu_cam_get_center_array()
 {
     return centerLine;
 }
 
 void image_processing()
 {
+    static uint8_t leftPos = 0;
+    static uint8_t rightPos = 0;
+    static uint8_t isBorderFound = BOTH_NOT_FOUND;
     
+    static uint8_t leftNearCenter1 = lineArrayEnd;
+    static uint8_t leftNearPos = 0;
+    static uint8_t rightNearCenter1 = leftNearCenter1;
+    static uint8_t rightNearPos = RESOLUTION_WIDTH;
     //while(true)
     {
         ardu_cam_start_capture();
@@ -240,7 +249,8 @@
         static float calTemp = 0.0f;
         calTemp = 0.0f;
         static uint16_t greenPixel = 0x00;
-        uint8_t isValid = 1;
+        static uint8_t isValid = 1;
+        isValid = 1;
         for (uint8_t j = 0; j < RESOLUTION_WIDTH; ++j)
         {
             if(CAM_BLK_CAL_LEFT < j && j <= CAM_BLK_CAL_RIGHT)
@@ -268,15 +278,16 @@
         }
 #endif
         //cal_black_calibrate();
-        uint8_t leftPos = 0;
-        uint8_t rightPos = 0;
-        uint8_t isBorderFound = BOTH_NOT_FOUND;
+        intersection_info = INTERSECTION_NULL;
         
-        is_intersection_detected = 0;
-        uint8_t leftNearCenter1 = 0;
-        uint8_t leftNearCenter2 = 0;
-        uint8_t rightNearCenter1 = 0;
-        uint8_t rightNearCenter2 = 0;
+        leftPos = 0;
+        rightPos = 0;
+        isBorderFound = BOTH_NOT_FOUND;
+        
+        leftNearCenter1 = lineArrayEnd;
+        leftNearPos = 0;
+        rightNearCenter1 = leftNearCenter1;
+        rightNearPos = RESOLUTION_WIDTH;
         
         is_encounter_terminate = 0;
         for (uint8_t i = 0; i < CAM_ROI_UPPER_LIMIT; ++i)
@@ -286,7 +297,8 @@
 #endif
             get_img_row_info(i, &leftPos, &rightPos, &isBorderFound);
             temp_mid_pos = (leftPos + rightPos) / 2;
-            uint8_t dis_btw_left_right = rightPos - leftPos - 1;
+    static uint8_t dis_btw_left_right;
+            dis_btw_left_right = rightPos - leftPos - 1;
             if(dis_btw_left_right < TERMINATE_WIDTH)
             {
                 is_encounter_terminate = 1;
@@ -296,27 +308,47 @@
             ardu_utft_set_camimg_rowcol(CAM_ROI_UPPER_LIMIT - i, temp_mid_pos);
             ardu_utft_write_DATA(0xF8, 0x00);
 #endif
-
-            centerLine[CAM_ROI_UPPER_LIMIT - i - 1] = temp_mid_pos;
-            centerLine[(2 * CAM_ROI_UPPER_LIMIT) - i - 1] = isBorderFound;
+    static uint8_t array_pos;
+            array_pos = lineArrayEnd - i;
+            centerLine[array_pos] = temp_mid_pos;
+            leftLine[array_pos] = leftPos;
+            rightLine[array_pos] = rightPos;
             
-            if(leftPos > leftNearCenter1)
+            centerLine[(2 * CAM_ROI_UPPER_LIMIT) - 1 - i] = isBorderFound;
+            
+            if(leftPos >= leftNearPos)
             {
-                leftNearCenter2 = leftNearCenter1; 
-                leftNearCenter1 = CAM_ROI_UPPER_LIMIT - i - 1;
+                leftNearCenter1 = lineArrayEnd - i;
+                leftNearPos = leftPos;
             }
-            if(rightPos < rightNearCenter1)
+            if(rightPos <= rightNearPos)
             {
-                rightNearCenter2 = rightNearCenter1;
-                rightNearCenter1 = CAM_ROI_UPPER_LIMIT - i - 1;
+                rightNearCenter1 = lineArrayEnd - i;
+                rightNearPos = rightPos;
             }
         }
+        if( (0 < rightNearCenter1 && rightNearCenter1 < lineArrayEnd) 
+            && ((rightLine[0] - rightLine[rightNearCenter1]) >= 4)
+            )
+        {
+            intersection_info = INTERSECTION_IN_R;
+        }
         
-        if( ((1 < rightNearCenter1 && rightNearCenter1 < (CAM_ROI_UPPER_LIMIT - 2)) && (abs(rightNearCenter1 - rightNearCenter2) == 1)) ||
-            ((1 < leftNearCenter1 && leftNearCenter1 < (CAM_ROI_UPPER_LIMIT - 2)) && (abs(leftNearCenter1 - leftNearCenter1) == 1)) )
+        if( (0 < leftNearCenter1 && leftNearCenter1 < lineArrayEnd) 
+            && ((leftLine[leftNearCenter1] - leftLine[0]) >= 4)
+            )
         {
-            is_intersection_detected = 1;
+            switch(intersection_info)
+            {
+            case INTERSECTION_IN_R:
+                intersection_info = INTERSECTION_IN;
+                break;
+            default:
+                intersection_info = INTERSECTION_IN_L;
+                break;
+            }
         }
+        //LOGI("#%d,%d,%d#", rightNearCenter1, abs(rightLine[0] - rightLine[rightNearCenter1]), abs(rightLine[lineArrayEnd] - rightLine[rightNearCenter1]));
     }
 }
 
@@ -432,9 +464,9 @@
     return ardu_cam_spi_read_8(ARDUCHIP_VER);
 }
 
-uint8_t ardu_cam_get_is_intersection_detected()
+uint8_t ardu_cam_get_intersection_info()
 {
-    return is_intersection_detected;
+    return intersection_info;
 }
 
 #ifdef __cplusplus