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
Diff: Hardwares/ArduCAM.cpp
- 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