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:
57:0d8a155d511d
Parent:
56:7d3395ae022d
Child:
63:d9a81b3d69f5
--- a/Hardwares/ArduCAM.cpp	Thu Apr 06 22:19:59 2017 +0000
+++ b/Hardwares/ArduCAM.cpp	Sat Apr 08 15:58:52 2017 +0000
@@ -1,6 +1,6 @@
 #include "ArduCAM.h"
 
-#define SW_DEBUG
+//#define SW_DEBUG
 #include "GlobalVariable.h"
 #include "SWCommon.h"
 
@@ -11,26 +11,32 @@
 
 #include <string>
 
-#define CAM_BLK_CAL_LEFT    ((RESOLUTION_WIDTH / 2) - 2)
-#define CAM_BLK_CAL_RIGHT   ((RESOLUTION_WIDTH / 2) + 2)
+#define CAM_BLK_CAL_ACTIVE
 
 //#define CAM_DISP_DEBUG
 //#define CAM_DISP_DEBUG_CENTER
 //#define CAM_DISP_IMG
 
+#define IMG_PROC_SIGNAL 0xBB
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+const static uint8_t CAM_BLK_CAL_LEFT  = ((RESOLUTION_WIDTH / 2) - 1);
+const static uint8_t CAM_BLK_CAL_RIGHT = ((RESOLUTION_WIDTH / 2) + 1);
+
 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];
 static Thread * m_imgProcessThread = NULL;
+static Ticker m_tickerImgProc;
 
-void image_processing();
+//void image_processing();
 void cal_black_calibrate();
+void tick_image_proc();
 
 inline void ardu_cam_spi_write_8(int address, int value)
 {
@@ -148,8 +154,10 @@
     //sprintf(buf, "Ardu FS1 %#x", tempV);
     //g_core.GetUSBServer().PushReliableMsg('D', buf);
     cal_black_calibrate();
-    m_imgProcessThread = new Thread;
-    m_imgProcessThread->start(callback(image_processing));
+    //m_imgProcessThread = new Thread(osPriorityRealtime); //osPriorityAboveNormal //osPriorityHigh //osPriorityRealtime
+    //m_imgProcessThread->set_priority(osPriorityRealtime);
+    //m_imgProcessThread->start(callback(image_processing));
+    //m_tickerImgProc.attach(&tick_image_proc, 0.1f);
     
     return true;
 }
@@ -291,14 +299,6 @@
     *left = 0;
     *right = RESOLUTION_WIDTH;
     uint8_t isRightFound = 0;
-/*
-#ifdef IMAGE_DISPLAY_TO_SCREEN
-    if(display)
-    {
-        ardu_utft_set_camimg_row(CAM_ROI_UPPER_LIMIT - rowI);
-    }
-#endif
-*/
     static uint16_t pixel = 0x0000;
     static uint8_t pGreen = 0x00;
     
@@ -307,7 +307,7 @@
         pixel = static_cast<uint16_t>(ardu_cam_spi_read_8(SINGLE_FIFO_READ)) << 8;
         pixel = pixel | ardu_cam_spi_read_8(SINGLE_FIFO_READ);
 
-        pGreen = static_cast<uint8_t>((pixel >> 3) & 0x00FF);
+        pGreen = static_cast<uint8_t>((pixel & 0x07E0) >> 3);
         if((pGreen < black_calibrate))
         {
             if(j < temp_mid_pos)
@@ -345,17 +345,48 @@
 
 void image_processing()
 {
-    while(true)
+    DebugCounter counter(10, PTE4);
+    //while(true)
     {
         ardu_cam_start_capture();
     
         while (!(ardu_cam_spi_read_8(ARDUCHIP_TRIG) & CAP_DONE_MASK));
         
         temp_mid_pos = RESOLUTION_WIDTH / 2;
+#ifdef CAM_BLK_CAL_ACTIVE
+        static float calTemp = 0.0f;
+        calTemp = 0.0f;
+        static uint16_t greenPixel = 0x00;
+        for (uint8_t j = 0; j < RESOLUTION_WIDTH; ++j)
+        {
+            if(CAM_BLK_CAL_LEFT < j && j <= CAM_BLK_CAL_RIGHT)
+            {
+                greenPixel = static_cast<uint16_t>(ardu_cam_spi_read_8(SINGLE_FIFO_READ)) << 8;
+                greenPixel = greenPixel | ardu_cam_spi_read_8(SINGLE_FIFO_READ);
+                greenPixel = (greenPixel & 0x07E0) >> 3;
+                calTemp += static_cast<uint8_t>(greenPixel);
+            }
+            else
+            {
+                ardu_cam_spi_read_8(SINGLE_FIFO_READ);
+                ardu_cam_spi_read_8(SINGLE_FIFO_READ);
+            }
+        }
+        calTemp = calTemp / static_cast<float>(CAM_BLK_CAL_RIGHT - CAM_BLK_CAL_LEFT);
+        black_calibrate = static_cast<uint8_t>(calTemp * 0.7f);
+#endif
         //cal_black_calibrate();
         uint8_t leftPos = 0;
         uint8_t rightPos = 0;
         for (uint8_t i = 0; i < CAM_ROI_UPPER_LIMIT; ++i)
+        /*{
+            for (uint8_t j = 0; j < RESOLUTION_WIDTH; ++j)
+            {
+                ardu_cam_spi_read_8(SINGLE_FIFO_READ);
+                ardu_cam_spi_read_8(SINGLE_FIFO_READ);
+            }
+        }*/
+        //for(uint8_t i = CAM_ROI_UPPER_LIMIT; i < (2 * CAM_ROI_UPPER_LIMIT); ++i)
         {
 #if defined(CAM_DISP_IMG) or defined(CAM_DISP_DEBUG)
             ardu_utft_set_camimg_row(CAM_ROI_UPPER_LIMIT - i);
@@ -371,6 +402,9 @@
             centerLine[CAM_ROI_UPPER_LIMIT - i - 1] = temp_mid_pos;
         }
         
+        
+        counter.Update();
+        //Thread::signal_wait(IMG_PROC_SIGNAL, osWaitForever);
     }
 }
 
@@ -397,6 +431,11 @@
     }
 }
 
+void tick_image_proc()
+{
+    m_imgProcessThread->signal_set(IMG_PROC_SIGNAL);
+}
+
 #ifdef __cplusplus
 }
 #endif