diff --git a/app/gl_circle.c b/app/gl_circle.c new file mode 100644 index 0000000..16d69a7 --- /dev/null +++ b/app/gl_circle.c @@ -0,0 +1,161 @@ +#include "zf_common_headfile.h" +#include "gl_headfile.h" + +enum circle_type_e circle_type = CIRCLE_NONE; + + +int32_t Left_Border_None_Circle = 0; +int32_t Right_Border_None_Circle = 0; + +int32_t Left_Border_Have_Circle = 0; +int32_t Right_Border_Have_Circle = 0; + +int32_t Left_Border_ToLeft_Circle = 0; +int32_t Right_Border_ToLeft_Circle = 0; + +int32_t Left_Border_ToRight_Circle = 0; +int32_t Right_Border_ToRight_Circle = 0; + + +void CheckCircle() { + // 非圆环模式下,单边L角点, 单边长直道 + if (circle_type == CIRCLE_NONE && Lpt0_found && !Lpt1_found && is_straight1) { + circle_type = CIRCLE_LEFT_BEGIN; + } + if (circle_type == CIRCLE_NONE && !Lpt0_found && Lpt1_found && is_straight0) { + circle_type = CIRCLE_RIGHT_BEGIN; + } +} + + +void RunCircle() { + if (circle_type == CIRCLE_LEFT_BEGIN) // 左环开始,寻外直道右线 + { + track_type = TRACK_RIGHT; + + // 先丢左线后有线 + if (pts_resample_left_count < 0.1 / RESAMPLEDIST) { + Left_Border_None_Circle++; + } + if (pts_resample_left_count > 0.5 / RESAMPLEDIST &&Left_Border_None_Circle > FRAMENONE) { + Left_Border_Have_Circle++; + if (Left_Border_Have_Circle > FRAMENONE) { + circle_type = CIRCLE_LEFT_IN; + Left_Border_None_Circle = 0; + Left_Border_Have_Circle = 0; + } + } + } else if (circle_type == CIRCLE_LEFT_IN) // 入环,寻内圆左线 + { + track_type = TRACK_LEFT; + + if (pts_resample_right[(int32_t)(0.2 / RESAMPLEDIST)][1] - + pts_resample_right[0][1] < + -2) { + Right_Border_ToLeft_Circle++; + } + if (Right_Border_ToLeft_Circle > FRAMETOLEFT) { + circle_type = CIRCLE_LEFT_RUNNING; + Right_Border_ToLeft_Circle = 0; + } + } else if (circle_type == CIRCLE_LEFT_RUNNING) // 正常巡线,寻外圆右线 + { + // Track_Type = TRACK_RIGHT; + track_type = TRACK_LEFT; // 看看加一个如果丢线才切换 + if (Lpt1_found) { + pts_resample_right_count = mid_right_count = Lpt1_rpts1s_id; + } + if (Lpt1_found && Lpt1_rpts1s_id < 0.4 / RESAMPLEDIST) { + circle_type = CIRCLE_LEFT_OUT; + } + } else if (circle_type == CIRCLE_LEFT_OUT) // 出环,寻内圆 + { + track_type = TRACK_LEFT; + + if (is_straight1) // 右线为长直道 + { + circle_type = CIRCLE_LEFT_END; + } + } else if (circle_type == CIRCLE_LEFT_END) // 走过圆环,寻右线 + { + track_type = TRACK_RIGHT; + + if (pts_resample_left_count < 0.2 / RESAMPLEDIST) // 左线先丢后有 + { + Left_Border_None_Circle++; + } + if (pts_resample_left_count > 0.6 / RESAMPLEDIST && + Left_Border_None_Circle > FRAMENONE) { + circle_type = CIRCLE_NONE; + Left_Border_None_Circle = 0; + Left_Border_Have_Circle = 0; + Right_Border_ToLeft_Circle = 0; + Right_Border_ToRight_Circle = 0; + } + } else if (circle_type == CIRCLE_RIGHT_BEGIN) // 右环控制,前期寻左直道 + { + track_type = TRACK_LEFT; + + // 先丢右线后有线 + if (pts_resample_right_count < 0.3 / RESAMPLEDIST) { + Right_Border_None_Circle++; + } + if (pts_resample_right_count > 0.5 / RESAMPLEDIST && + Right_Border_None_Circle > FRAMENONE) { + Right_Border_Have_Circle++; + if (Right_Border_Have_Circle > FRAMENONE) { + circle_type = CIRCLE_RIGHT_IN; + Right_Border_None_Circle = 0; + Right_Border_Have_Circle = 0; + } + } + } else if (circle_type == CIRCLE_RIGHT_IN) // 入右环,寻右内圆环 + { + track_type = TRACK_RIGHT; + + if (pts_resample_left[(int32_t)(0.2 / RESAMPLEDIST)][1] - + pts_resample_left[0][1] > + 2) { + Left_Border_ToRight_Circle++; + } + if (Left_Border_ToRight_Circle > FRAMETORIGHT) { + circle_type = CIRCLE_RIGHT_RUNNING; + Left_Border_ToRight_Circle = 0; + } + } else if (circle_type == CIRCLE_RIGHT_RUNNING) // 正常巡线,寻外圆左线 + { + // track_type = TRACK_LEFT; + track_type = TRACK_RIGHT; // 看看加一个如果丢线才切换 + if (Lpt0_found) // 外环存在拐点,可再加拐点距离判据 (左 L 点) + { + pts_resample_left_count = mid_left_count = Lpt0_rpts0s_id; + } + if (Lpt0_found && Lpt0_rpts0s_id < 0.4 / RESAMPLEDIST) { + circle_type = CIRCLE_RIGHT_OUT; + } + } else if (circle_type == CIRCLE_RIGHT_OUT) // 出环,寻内圆 + { + track_type = TRACK_RIGHT; + + if (is_straight0) // 加个有线长度判断 + { + circle_type = CIRCLE_RIGHT_END; + } + } else if (circle_type == CIRCLE_RIGHT_END) // 走过圆环,寻左线 + { + track_type = TRACK_LEFT; + + if (pts_resample_right_count < 0.2 / RESAMPLEDIST) // 左线先丢后有 + { + Right_Border_None_Circle++; + } + if (pts_resample_right_count > 0.7 / RESAMPLEDIST && + Right_Border_None_Circle > FRAMENONE) { + circle_type = CIRCLE_NONE; + Right_Border_None_Circle = 0; + Right_Border_Have_Circle = 0; + Left_Border_ToLeft_Circle = 0; + Left_Border_ToRight_Circle = 0; + } + } +} diff --git a/app/gl_circle.h b/app/gl_circle.h new file mode 100644 index 0000000..1ddeb7e --- /dev/null +++ b/app/gl_circle.h @@ -0,0 +1,24 @@ +#ifndef CIRCLE +#define CIRCLE + + +enum circle_type_e { + CIRCLE_NONE, // 非圆环模式 + CIRCLE_LEFT_BEGIN, + CIRCLE_RIGHT_BEGIN, // 圆环开始,识别到单侧L角点另一侧长直道。 + CIRCLE_LEFT_IN, + CIRCLE_RIGHT_IN, // 圆环进入,即走到一侧直道,一侧圆环的位置。 + CIRCLE_LEFT_RUNNING, + CIRCLE_RIGHT_RUNNING, // 圆环内部。 + CIRCLE_LEFT_OUT, + CIRCLE_RIGHT_OUT, // 准备出圆环,即识别到出环处的L角点。 + CIRCLE_LEFT_END, + CIRCLE_RIGHT_END // 圆环结束,即再次走到单侧直道的位置。 +}; + +extern enum circle_type_e circle_type; + +void CheckCircle(void); +void RunCircle(void); + +#endif /* COMMON_H_ */ \ No newline at end of file diff --git a/app/gl_common.c b/app/gl_common.c new file mode 100644 index 0000000..29a3138 --- /dev/null +++ b/app/gl_common.c @@ -0,0 +1,15 @@ +#include "zf_common_headfile.h" +#include "gl_headfile.h" + + +sint32 limit(sint32 x, sint32 low, sint32 up) +{ + return x > up ? up : x < low ? low : x; +} + int clip(int x, int low, int up) { + return x > up ? up : x < low ? low : x; + } + +float fclip(float x, float low, float up) { + return x > up ? up : x < low ? low : x; + } diff --git a/app/gl_common.h b/app/gl_common.h new file mode 100644 index 0000000..1bd003a --- /dev/null +++ b/app/gl_common.h @@ -0,0 +1,35 @@ +#ifndef COMMON_H_ +#define COMMON_H_ + + + +#define IMAGE_H (MT9V03X_H) +#define IMAGE_W (MT9V03X_W) +#define BEGINH_L (61) +#define BEGINH_R (61) +#define BEGINW_L (-18) +#define BEGINW_R (-12) +#define PT_MAXLEN (75) +#define GET_PIX_1C(IMG, H, W) (IMG[(H) * MT9V03X_W + (W)]) //获取像素点的值 +#define FIX_BINTHRESHOLD (140) //设置最开始的阈值 +#define SELFADAPT_KERNELSIZE (7) //巡线区域核大小 +#define FILTER_KERNELSIZE (7) //滤波核大小 +#define SELFADAPT_OFFSET (8) //适应性块大小 +#define PIXPERMETER (56) +#define RESAMPLEDIST (0.02) +#define ANGLEDIST (0.2) +#define ROADWIDTH (0.45) +#define FRAMENONE (1) +#define FRAMETOLEFT (5) +#define FRAMETORIGHT (5) + +typedef signed int sint32; +typedef float float32; + +sint32 limit(sint32 x, sint32 low, sint32 up); +int clip(int x, int low, int up); +float fclip(float x, float low, float up) ; + + + +#endif /* COMMON_H_ */ \ No newline at end of file diff --git a/app/gl_cross.c b/app/gl_cross.c new file mode 100644 index 0000000..6c08a20 --- /dev/null +++ b/app/gl_cross.c @@ -0,0 +1,57 @@ +#include "zf_common_headfile.h" +#include "gl_headfile.h" + +enum cross_type_e cross_type = CROSS_NONE; +bool far_Lpt0_found, far_Lpt1_found; +int32_t Both_Boder_None_Cross; + +void CheckCross() { + bool Xfound = Lpt0_found && Lpt1_found; + if (cross_type == CROSS_NONE && Xfound){ + cross_type = CROSS_BEGIN; + } +} + +void RunCross() { + bool Xfound = Lpt0_found && Lpt1_found; + aim_distance = 0.4; + //检测到十字,先按照近线走 + if (cross_type == CROSS_BEGIN) { + if (Lpt0_found) { + mid_left_count = pts_resample_left_count = Lpt0_rpts0s_id; + track_type = TRACK_LEFT; + } + if (Lpt1_found) { + mid_right_count = pts_resample_right_count = Lpt1_rpts1s_id; + track_type = TRACK_RIGHT; + } + + //近角点过少,进入远线控制 + if ((Xfound && (Lpt0_rpts0s_id < 0.2 / RESAMPLEDIST || Lpt1_rpts1s_id < 0.2 / RESAMPLEDIST)) || (pts_resample_left_count <20 && pts_resample_right_count<20)) { + cross_type = CROSS_IN; + //cross_encoder = current_encoder; + } + + } + //远线控制进十字,begin_y渐变靠近防丢线 + else if (cross_type == CROSS_IN) { + //寻远线,算法与近线相同 + cross_farline(); + + if (pts_resample_left_count < 5 && pts_resample_right_count < 5) { + Both_Boder_None_Cross++; + } + if (Both_Boder_None_Cross > 2 && pts_resample_left_count > 20 && pts_resample_right_count > 20) { + cross_type = CROSS_NONE; + Both_Boder_None_Cross = 0; + } + if (far_Lpt1_found) { track_type = TRACK_RIGHT; } + else if (far_Lpt0_found) { track_type = TRACK_LEFT; } + else if (Both_Boder_None_Cross > 0 && pts_resample_right_count < 5) { track_type = TRACK_RIGHT; } + else if (Both_Boder_None_Cross > 0 && pts_resample_left_count < 5) { track_type = TRACK_LEFT; } + + } +} + + +void cross_farline(){} \ No newline at end of file diff --git a/app/gl_cross.h b/app/gl_cross.h new file mode 100644 index 0000000..9c5920b --- /dev/null +++ b/app/gl_cross.h @@ -0,0 +1,18 @@ +#ifndef CROSS +#define CROSS + + +enum cross_type_e { + CROSS_NONE, // 非十字模式 + CROSS_BEGIN, // 找到左右两个L角点 + CROSS_IN, // 两个L角点很近,即进入十字内部(此时切换远线控制) +}; +extern enum cross_type_e cross_type; +extern int32_t Both_Boder_None_Cross; + +void CheckCross(void); +void RunCross(void); +void cross_farline(void); + + +#endif /* COMMON_H_ */ \ No newline at end of file diff --git a/app/gl_garage.c b/app/gl_garage.c new file mode 100644 index 0000000..7bbb4a8 --- /dev/null +++ b/app/gl_garage.c @@ -0,0 +1,23 @@ +#include "zf_common_headfile.h" +#include "math.h" +#include "gl_headfile.h" + +enum garage_type_e garage_type = GARAGE_NONE; + +float (*garage_rpts)[2]; +int garage_rpts_num; + +float calculate_vector_angle(float x1, float y1, float x2, float y2) { + float dx = x2 - x1; + float dy = y2 - y1; + + float vector_length = sqrt(dx*dx + dy*dy); + float angle_radians = acos(dx / vector_length); + float angle_degrees = angle_radians * 180 / M_PI; + + return angle_degrees; +} + +void CheckGarage() {} + +void RunGarage(){} \ No newline at end of file diff --git a/app/gl_garage.h b/app/gl_garage.h new file mode 100644 index 0000000..ee634c4 --- /dev/null +++ b/app/gl_garage.h @@ -0,0 +1,23 @@ +#ifndef GARAGE +#define GARAGE + + +enum garage_type_e { + GARAGE_NONE, // 非车库模式 + GARAGE_OUT_LEFT, + GARAGE_OUT_RIGHT, // 出库,陀螺仪转过45°,即出库完毕 + GARAGE_FOUND_LEFT, + GARAGE_FOUND_RIGHT, // 发现车库,即斑马线+单侧L角点(未使用) + GARAGE_IN_LEFT, + GARAGE_IN_RIGHT, // 进库,发现车库后判断第几次,从而决定是否进库 + GARAGE_PASS_LEFT, + GARAGE_PASS_RIGHT, // 不进库,发现车库后判断第几次,从而决定是否进库 + GARAGE_STOP // 进库完毕,停车 +}; +extern enum garage_type_e garage_type; + +float calculate_vector_angle(float x1, float y1, float x2, float y2);\ +void CheckGarage(void); +void RunGarage(void); + +#endif /* COMMON_H_ */ \ No newline at end of file diff --git a/app/gl_get_corners.c b/app/gl_get_corners.c new file mode 100644 index 0000000..2d8fcd1 --- /dev/null +++ b/app/gl_get_corners.c @@ -0,0 +1,88 @@ +#include "zf_common_headfile.h" +#include "math.h" +#include "gl_headfile.h" + + + +void get_corners() { + // + Lpt0_found = Lpt1_found = false; + Lpt_in0_found = Lpt_in1_found = false; + is_straight0 = pts_resample_left_count > 1.0 / RESAMPLEDIST; + is_straight1 = pts_resample_right_count > 1.0 / RESAMPLEDIST; + for (int i = 0; i < pts_resample_left_count; i++) { + if (angle_new_left[i] == 0) continue; + int im1 = clip(i - (int) round(ANGLEDIST / RESAMPLEDIST), 0, pts_resample_left_count - 1); + int ip1 = clip(i + (int) round(ANGLEDIST / RESAMPLEDIST), 0, pts_resample_left_count - 1); + float conf = fabs(angle_left[i]) - (fabs(angle_left[im1]) + fabs(angle_left[ip1])) / 2; + + //L角点阈值 + if (Lpt0_found == false && (66. / 180. * PI) < conf && conf < (140. / 180. * PI) && i < 0.7 / RESAMPLEDIST) { + Lpt0_rpts0s_id = i; + Lpt0_found = true; + transform(pts_resample_left[Lpt0_rpts0s_id][1],pts_resample_left[Lpt0_rpts0s_id][0],&Lpt0[1],&Lpt0[0]); + } + //长直道阈值 + if (conf > (7. / 180. * PI) && i < 0.8 / RESAMPLEDIST) is_straight0 = false; + if (Lpt0_found == true && is_straight0 == false) break; + } + if(Lpt0_found){ + float angle1 = calculate_vector_angle(pts_resample_left[Lpt0_rpts0s_id][1],pts_resample_left[Lpt0_rpts0s_id][0],pts_resample_left[Lpt0_rpts0s_id+5][1],pts_resample_left[Lpt0_rpts0s_id+5][0]); + if(angle1 < 85.) { + Lpt_in0_found = true; + Lpt0_found = false; + Lpt_in0_rpts0s_id = Lpt0_rpts0s_id; + } + } + else{ + is_turn0 = is_curve(angle_left ,clip(angle_left_num - 10, 0,angle_left_num),0.05); + if(is_turn0){ + state_type = TURN_STATE; + } + } + if(is_straight0){ + state_type = STRAIGHT_STATE; + } + + + + + for (int i = 0; i < pts_resample_right_count; i++) { + if (angle_new_right[i] == 0) continue; + int im1 = clip(i - (int) round(ANGLEDIST / RESAMPLEDIST), 0, pts_resample_right_count - 1); + int ip1 = clip(i + (int) round(ANGLEDIST / RESAMPLEDIST), 0, pts_resample_right_count - 1); + float conf = fabs(angle_right[i]) - (fabs(angle_right[im1]) + fabs(angle_right[ip1])) / 2; + + + if (Lpt1_found == false && (66. / 180. * PI) < conf && conf < 140. / 180. * PI && i < 0.7 / RESAMPLEDIST) { + Lpt1_rpts1s_id = i; + Lpt1_found = true; + transform(pts_resample_right[Lpt1_rpts1s_id][1],pts_resample_right[Lpt1_rpts1s_id][0],&Lpt1[1],&Lpt1[0]); + } + + if (conf > (7. / 180. * PI) && i < 0.8 / RESAMPLEDIST) is_straight1 = false; + if (Lpt1_found == true && is_straight1 == false) break; + } + if(Lpt1_found){ + float angle2 = calculate_vector_angle(pts_resample_right[Lpt1_rpts1s_id][1],pts_resample_right[Lpt1_rpts1s_id][0],pts_resample_right[Lpt1_rpts1s_id+5][1],pts_resample_right[Lpt1_rpts1s_id+5][0]); + if(angle2 > 100.) { + Lpt_in1_found = true; + Lpt1_found = false; + Lpt_in1_rpts1s_id = Lpt1_rpts1s_id; + } + }else{ + is_turn1 = is_curve(angle_right, clip(angle_right_num - 10,0 ,angle_right_num), 0.05); + if(is_turn1){ + state_type = TURN_STATE; + } + } + if(is_straight1){ + state_type = STRAIGHT_STATE; + } + + // + + +} + + diff --git a/app/gl_get_corners.h b/app/gl_get_corners.h new file mode 100644 index 0000000..aff31b2 --- /dev/null +++ b/app/gl_get_corners.h @@ -0,0 +1,8 @@ +#ifndef GET_CORNERS +#define GET_CORNERS + + +void get_corners(void); + + +#endif /* COMMON_H_ */ \ No newline at end of file diff --git a/app/gl_handle_img.c b/app/gl_handle_img.c new file mode 100644 index 0000000..1e12c62 --- /dev/null +++ b/app/gl_handle_img.c @@ -0,0 +1,236 @@ +#include "zf_common_headfile.h" +#include "math.h" +#include "gl_headfile.h" + + + + +const sint32 direction_front[4][2] = {{0, -1},{1, 0},{0, 1},{-1, 0}}; +const sint32 direction_frontleft[4][2] = {{-1, -1},{1, -1},{1, 1},{-1, 1}}; +const sint32 direction_frontright[4][2] ={{1, -1},{1, 1},{-1, 1},{-1, -1}}; + + +void SearchLineAdaptive_Left(uint8 img_gray[], sint32 block_size, sint32 down_value, sint32 h, sint32 w, sint32 pts[][2], sint32* line_num) +{ + int half = block_size / 2; + int step = 0, dir = 0, turn = 0; + while (step < *line_num && half < w && w < IMAGE_W - half -1 && half < h && h < IMAGE_H - half -1 && turn < 4) { + int local_thres = 0; + for (int dh = -half; dh <= half; dh++) { + for (int dw = -half; dw <= half; dw++) { + local_thres += GET_PIX_1C(img_gray, h + dh, w + dw); + } + } + local_thres /= block_size * block_size; + local_thres -= down_value; + + int front_value = GET_PIX_1C(img_gray, h+direction_front[dir][1], w + direction_front[dir][0]); + int frontleft_value = GET_PIX_1C(img_gray, h + direction_frontleft[dir][1], w + direction_frontleft[dir][0]); + if (front_value < local_thres) { + dir = (dir + 1) % 4; + turn++; + } else if (frontleft_value < local_thres) { + w += direction_front[dir][0]; + h += direction_front[dir][1]; + pts[step][1] = w; + pts[step][0] = h; + step++; + turn = 0; + } else { + + w += direction_frontleft[dir][0]; + h += direction_frontleft[dir][1]; + dir = (dir + 3) % 4; + pts[step][1] = w; + pts[step][0] = h; + step++; + turn = 0; + + } + + + } + *line_num = step; +} + +void SearchLineAdaptive_Right(uint8 img_gray[], sint32 block_size, sint32 down_value, sint32 h, sint32 w, sint32 pts[][2], sint32* line_num) +{ + int half = block_size / 2; + int step = 0, dir = 0, turn = 0; + while (step < *line_num && 0 < w && w < IMAGE_W - 1 && 0 < h && h < IMAGE_H -1 && turn < 4) { + int local_thres = 0; + for (int dh = -half; dh <= half; dh++) { + for (int dw = -half; dw <= half; dw++) { + local_thres += GET_PIX_1C(img_gray, h + dh, w + dw); + } + } + local_thres /= block_size * block_size; + local_thres -= down_value; + + + int front_value = GET_PIX_1C(img_gray, h + direction_front[dir][1], w + direction_front[dir][0]); + int frontright_value = GET_PIX_1C(img_gray, h + direction_frontright[dir][1], w + direction_frontright[dir][0]); + if (front_value < local_thres) { + dir = (dir + 3) % 4; + turn++; + } else if (frontright_value < local_thres) { + w += direction_front[dir][0]; + h += direction_front[dir][1]; + pts[step][1] = w; + pts[step][0] = h; + step++; + turn = 0; + + + } else { + w += direction_frontright[dir][0]; + h += direction_frontright[dir][1]; + dir = (dir + 1) % 4; + pts[step][1] = w; + pts[step][0] = h; + step++; + turn = 0; + + + } + + } + *line_num = step; +} + + + +void GetLinesFilter(float32 pts_in[][2], sint32 pts_in_count, float32 pts_out[][2], sint32 kernelsize) +{ + int half = kernelsize / 2; + for (int i = 0; i < pts_in_count; i++) { + pts_out[i][0] = 0; + pts_out[i][1] = 0; + for (int j = -half; j <= half; j++) { + pts_out[i][0] += pts_in[clip(i + j, 0, pts_in_count - 1)][0] * (half + 1 - abs(j)); + pts_out[i][1] += pts_in[clip(i + j, 0, pts_in_count - 1)][1] * (half + 1 - abs(j)); + } + pts_out[i][0] /= (2 * half + 2) * (half + 1) / 2; + pts_out[i][1] /= (2 * half + 2) * (half + 1) / 2; + } +} + +void GetLinesResample(float32 pts_in[][2], sint32 num1, float32 pts_out[][2], sint32* num2, float32 dist) +{ + if (num1 < 0) { + *num2 = 0; + return; + } + pts_out[0][0] = pts_in[0][0]; + pts_out[0][1] = pts_in[0][1]; + int len = 1; + for (int i = 0; i < num1 - 1 && len < *num2; i++) { + float x0 = pts_in[i][1]; + float y0 = pts_in[i][0]; + float x1 = pts_in[i + 1][1]; + float y1 = pts_in[i + 1][0]; + + do { + float x = pts_out[len - 1][1]; + float y = pts_out[len - 1][0]; + + float dx0 = x0 - x; + float dy0 = y0 - y; + float dx1 = x1 - x; + float dy1 = y1 - y; + + float dist0 = sqrt(dx0 * dx0 + dy0 * dy0); + float dist1 = sqrt(dx1 * dx1 + dy1 * dy1); + + float r0 = (dist1 - dist) / (dist1 - dist0); + float r1 = 1 - r0; + + if (r0 < 0 || r1 < 0) break; + x0 = x0 * r0 + x1 * r1; + y0 = y0 * r0 + y1 * r1; + pts_out[len][1] = x0; + pts_out[len][0] = y0; + len++; + } while (len < *num2); + + } + *num2 = len; +} + + +void local_angle_points(float pts_in[][2], int num, float angle_out[], int dist) { + for (int i = 0; i < num; i++) { + if (i <= 0 || i >= num - 1) { + angle_out[i] = 0; + continue; + } + float dx1 = pts_in[i][0] - pts_in[clip(i - dist, 0, num - 1)][0]; + float dy1 = pts_in[i][1] - pts_in[clip(i - dist, 0, num - 1)][1]; + float dn1 = sqrtf(dx1 * dx1 + dy1 * dy1); + float dx2 = pts_in[clip(i + dist, 0, num - 1)][0] - pts_in[i][0]; + float dy2 = pts_in[clip(i + dist, 0, num - 1)][1] - pts_in[i][1]; + float dn2 = sqrtf(dx2 * dx2 + dy2 * dy2); + float c1 = dx1 / dn1; + float s1 = dy1 / dn1; + float c2 = dx2 / dn2; + float s2 = dy2 / dn2; + angle_out[i] = atan2f(c1 * s2 - c2 * s1, c2 * c1 + s2 * s1); //得到弧度 类似angle_out = 0.3491 + } +} + +void nms_angle(float angle_in[], int num, float angle_out[], int kernel) { + + int half = kernel / 2; + for (int i = 0; i < num; i++) { + angle_out[i] = angle_in[i]; + for (int j = -half; j <= half; j++) { + if (fabs(angle_in[clip(i + j, 0, num - 1)]) > fabs(angle_out[i])) { + angle_out[i] = 0; + break; + } + } + } +} + +void GetMidLine_Left(float32 pts_left[][2], sint32 pts_left_count, float32 mid_left[][2], sint32 approx_num, float32 dist) +{ + for (int i = 0; i < pts_left_count; i++) { + float dx = pts_left[clip(i + approx_num, 0, pts_left_count - 1)][1] - pts_left[clip(i - approx_num, 0, pts_left_count - 1)][1]; + float dy = pts_left[clip(i + approx_num, 0, pts_left_count - 1)][0] - pts_left[clip(i - approx_num, 0, pts_left_count - 1)][0]; + float dn = sqrt(dx * dx + dy * dy); + dx /= dn; + dy /= dn; + mid_left[i][0] = pts_left[i][0] + dx * dist; + mid_left[i][1] = pts_left[i][1] - dy * dist; + } + +} + + +void GetMidLine_Right(float32 pts_right[][2], sint32 pts_right_count, float32 mid_right[][2], sint32 approx_num, float32 dist) +{ + for (int i = 0; i < pts_right_count; i++) { + float dx = pts_right[clip(i + approx_num, 0, pts_right_count -1)][1] - pts_right[clip(i - approx_num, 0, pts_right_count -1 )][1]; + float dy = pts_right[clip(i + approx_num, 0, pts_right_count -1)][0] - pts_right[clip(i - approx_num, 0, pts_right_count -1)][0]; + float dn = sqrt(dx * dx + dy * dy); + dx /= dn;//sin + dy /= dn;//cos + mid_right[i][0] = pts_right[i][0] - dx * dist; + mid_right[i][1] = pts_right[i][1] + dy * dist; + + + } +} + + +int is_curve(float32 angle[], int n, float32 threshold) { + for (int i = 1; i < n - 1; i++) { + float32 da = fabs(angle[i] - angle[i-1]); + float32 db = fabs(angle[i+1] - angle[i]); + if (da > threshold && db > threshold) { + return 1; // 是弯道 + } + } + return 0; // 不是弯道 +} + diff --git a/app/gl_handle_img.h b/app/gl_handle_img.h new file mode 100644 index 0000000..05f9470 --- /dev/null +++ b/app/gl_handle_img.h @@ -0,0 +1,15 @@ +#ifndef HANDLE_IMG +#define HANDLE_IMG + + + +void SearchStartPoint_Left(uint8 img_gray[], sint32* h_start, sint32* w_start, uint8 threshold); +void GetLinesFilter(float32 pts_in[][2], sint32 pts_in_count, float32 pts_out[][2], sint32 kernelsize); +void GetLinesResample(float32 pts_in[][2], sint32 num1, float32 pts_out[][2], sint32* num2, float32 dist); +void local_angle_points(float pts_in[][2], int num, float angle_out[], int dist); +void nms_angle(float angle_in[], int num, float angle_out[], int kernel); +void GetMidLine_Left(float32 pts_left[][2], sint32 pts_left_count, float32 mid_left[][2], sint32 approx_num, float32 dist); +void GetMidLine_Right(float32 pts_right[][2], sint32 pts_right_count, float32 mid_right[][2], sint32 approx_num, float32 dist); +int is_curve(float32 angle[], int n, float32 threshold) ; + +#endif /* COMMON_H_ */ \ No newline at end of file diff --git a/app/gl_headfile.h b/app/gl_headfile.h new file mode 100644 index 0000000..11591ce --- /dev/null +++ b/app/gl_headfile.h @@ -0,0 +1,21 @@ +#ifndef GL_HEADFILE +#define GL_HEADFILE + + + +#include "gl_state.h" +#include "gl_img_process.h" +#include "gl_common.h" +#include "main.h" +#include "gl_handle_img.h" +#include "gl_transform_table.h" +#include "gl_get_corners.h" +#include "gl_garage.h" +#include "gl_tracking.h" +#include "gl_circle.h" +#include "gl_cross.h" +#include "math.h" + + + +#endif /* STATE_H_ */ \ No newline at end of file diff --git a/app/gl_img_process.c b/app/gl_img_process.c new file mode 100644 index 0000000..c0bcbad --- /dev/null +++ b/app/gl_img_process.c @@ -0,0 +1,113 @@ +#include "zf_common_headfile.h" +#include "math.h" +#include "gl_headfile.h" +/*******************************边线处理****************************************/ +/* + @author: glz + @brief: + + + +*/ + + + +void img_processing() { + + int w1 = IMAGE_W / 2 - BEGINW_R, h1 = BEGINH_L; + pts_left_count = sizeof(pts_left) / sizeof(pts_left[0]); + for (; w1 > 0; w1--) { + if (GET_PIX_1C(mt9v03x_image_copy[0], h1, w1 - 1) < FIX_BINTHRESHOLD) + break; + } + + if (GET_PIX_1C(mt9v03x_image_copy[0], h1, w1) >= FIX_BINTHRESHOLD){ + SearchLineAdaptive_Left(mt9v03x_image_copy[0], SELFADAPT_KERNELSIZE, SELFADAPT_OFFSET, h1, w1, pts_left, &pts_left_count); + } + else pts_left_count = 0; + + int w2 = IMAGE_W / 2 + BEGINW_L, h2 = BEGINH_R; + pts_right_count = sizeof(pts_right) / sizeof(pts_right[0]); + for (; w2 < IMAGE_W - 1; w2++) { + if (GET_PIX_1C(mt9v03x_image_copy[0], h2, w2 + 1) < FIX_BINTHRESHOLD) + break; + } + + if (GET_PIX_1C(mt9v03x_image_copy[0], h2, w2) >= FIX_BINTHRESHOLD){ + SearchLineAdaptive_Right(mt9v03x_image_copy[0], SELFADAPT_KERNELSIZE, SELFADAPT_OFFSET, h2, w2, pts_right, &pts_right_count); + } + else pts_right_count = 0; + + //透视变换 + for (int i = 0; i < pts_left_count; i++) { + pts_inv_l[i][1] = fclip(UndistInverseMapW[pts_left[i][0]][pts_left[i][1]],0,IMAGE_W); + pts_inv_l[i][0] = fclip(UndistInverseMapH[pts_left[i][0]][pts_left[i][1]],0,IMAGE_H); + } + pts_inv_l_count = pts_left_count; + + for (int i = 0; i < pts_right_count; i++) { + pts_inv_r[i][1] = fclip(UndistInverseMapW[pts_right[i][0]][pts_right[i][1]],0,IMAGE_W); + pts_inv_r[i][0] = fclip(UndistInverseMapH[pts_right[i][0]][pts_right[i][1]],0,IMAGE_H); + } + pts_inv_r_count = pts_right_count;\ + + // 边线滤波 + GetLinesFilter(pts_inv_l, pts_inv_l_count, pts_filter_l, (int) round(FILTER_KERNELSIZE)); + pts_filter_l_count = pts_inv_l_count; + GetLinesFilter(pts_inv_r, pts_inv_r_count, pts_filter_r, (int) round(FILTER_KERNELSIZE)); + pts_filter_r_count = pts_inv_r_count; + + // 边线等距采样 + pts_resample_left_count = sizeof(pts_resample_left) / sizeof(pts_resample_left[0]); + GetLinesResample(pts_filter_l, pts_filter_l_count, pts_resample_left, &pts_resample_left_count, RESAMPLEDIST * PIXPERMETER); + pts_resample_right_count = sizeof(pts_resample_right) / sizeof(pts_resample_right[0]); + GetLinesResample(pts_filter_r, pts_filter_r_count, pts_resample_right, &pts_resample_right_count, RESAMPLEDIST * PIXPERMETER); + + int valid_points_count = 0; + + for (int i = 0; i < pts_resample_left_count; i++) { + int x = pts_resample_left[i][1]; + int y = pts_resample_left[i][0]; + + if (y < IMAGE_H-3 && x > 3 && x < IMAGE_W-3 && y>=3 ) { + pts_resample_left[valid_points_count][0] = pts_resample_left[i][0]; + pts_resample_left[valid_points_count][1] = pts_resample_left[i][1]; + valid_points_count++; + } + } + pts_resample_left_count = valid_points_count; + valid_points_count = 0; + + for (int i = 0; i < pts_resample_right_count; i++) { + int x = pts_resample_right[i][1]; + int y = pts_resample_right[i][0]; + + if (y <= IMAGE_H-3 && x >= 3 && x <= IMAGE_W-3 && y>=3) { + pts_resample_right[valid_points_count][0] = pts_resample_right[i][0]; + pts_resample_right[valid_points_count][1] = pts_resample_right[i][1]; + valid_points_count++; + } + } + + pts_resample_right_count = valid_points_count; + + // 边线角度变化率 + local_angle_points(pts_resample_left, pts_resample_left_count, angle_left, (int) round(ANGLEDIST / RESAMPLEDIST)); + angle_left_num = pts_resample_left_count; + local_angle_points(pts_resample_right, pts_resample_right_count, angle_right, (int) round(ANGLEDIST / RESAMPLEDIST)); + angle_right_num = pts_resample_right_count; + + // 角度变化率非极大值抑制 + nms_angle(angle_left, angle_left_num, angle_new_left, (int) round(ANGLEDIST / RESAMPLEDIST) * 2 + 1); + angle_new_left_num = angle_left_num; + nms_angle(angle_right, angle_right_num, angle_new_right, (int) round(ANGLEDIST / RESAMPLEDIST) * 2 + 1); + angle_new_right_num = angle_right_num; + + // 左右中线跟踪 + GetMidLine_Left(pts_resample_left, pts_resample_left_count, mid_left, (int) round(ANGLEDIST / RESAMPLEDIST), PIXPERMETER * ROADWIDTH / 2); + mid_left_count = pts_resample_left_count; + GetMidLine_Right(pts_resample_right, pts_resample_right_count, mid_right, (int) round(ANGLEDIST / RESAMPLEDIST), PIXPERMETER * ROADWIDTH / 2); + mid_right_count = pts_resample_right_count; + + +} \ No newline at end of file diff --git a/app/gl_img_process.h b/app/gl_img_process.h new file mode 100644 index 0000000..968f2e5 --- /dev/null +++ b/app/gl_img_process.h @@ -0,0 +1,12 @@ +#ifndef IMG_PROCESS +#define IMG_PROCESS + +#include "zf_common_headfile.h" + +typedef signed int sint32; + +void img_processing(void); +void SearchLineAdaptive_Left(uint8 img_gray[], sint32 block_size, sint32 down_value, sint32 h, sint32 w, sint32 pts[][2], sint32* line_num); +void SearchLineAdaptive_Right(uint8 img_gray[], sint32 block_size, sint32 down_value, sint32 h, sint32 w, sint32 pts[][2], sint32* line_num); + +#endif /* STATE_H_ */ diff --git a/app/gl_state.c b/app/gl_state.c new file mode 100644 index 0000000..04f94c8 --- /dev/null +++ b/app/gl_state.c @@ -0,0 +1,4 @@ +#include "gl_state.h" +#include "gl_headfile.h" + +enum state_type_e state_type =0; diff --git a/app/gl_state.h b/app/gl_state.h new file mode 100644 index 0000000..5a3c29f --- /dev/null +++ b/app/gl_state.h @@ -0,0 +1,22 @@ +#ifndef STATE_H_ +#define STATE_H_ + +enum state_type_e { + COMMON_STATE = 0, + CROSS_STATE,HALF_STATE, + CIRCLE_IN_STATE,CIRCLE_BEGIN_STATE, + CIRCLE_RUNNING_STATE,CIRCLE_OUT_STATE, + TURN_STATE,STRAIGHT_STATE, + BREAK_STATE,BAR_STATE, + RAMP_STATE,GARAGE_OUT_STATE, + GARAGE_IN_STATE,GARAGE_STOP_STATE, + GARAGE_PASS_STATE, +}; + +extern enum state_type_e state_type; + +#define CROSS_AIM (0.49) +#define COMMON_AIM (0.31) + + +#endif /* STATE_H_ */ diff --git a/app/gl_tracking.c b/app/gl_tracking.c new file mode 100644 index 0000000..b41eb73 --- /dev/null +++ b/app/gl_tracking.c @@ -0,0 +1,120 @@ +#include "zf_common_headfile.h" +#include "gl_headfile.h" + +float (*mid_track)[2]; +int32_t mid_track_count; +float near_angle; +float pure_angle; +float (*rpts)[2]; +int rpts_num; + + + +void tracking(){ + + if (pts_resample_left_count < pts_resample_right_count / 2 && pts_resample_left_count < 50) { + track_type = TRACK_RIGHT; + } else if (pts_resample_right_count < pts_resample_left_count / 2 && pts_resample_right_count < 58) { + track_type = TRACK_LEFT; + } else if (pts_resample_left_count < 20 && pts_resample_right_count > pts_resample_left_count) { + track_type = TRACK_RIGHT; + } else if (pts_resample_right_count < 20 && pts_resample_left_count > pts_resample_right_count) { + track_type = TRACK_LEFT; + } + +} + + + +void ElementJudge() { + CheckGarage(); + if (garage_type == GARAGE_NONE) { + CheckCross(); + if (cross_type == CROSS_NONE) { + CheckCircle(); + } + } +} + +void ElementRun() { + if (garage_type != GARAGE_NONE) { + RunGarage(); + } + + else if (cross_type != CROSS_NONE) { + RunCross(); + } + + else if (circle_type != CIRCLE_NONE) { + RunCircle(); + } +} + +void MidLineTrack() { + if (cross_type == CROSS_IN) { + if (track_type == TRACK_LEFT) { + } + } + else { + if (track_type == TRACK_LEFT) { + mid_track = mid_left; + mid_track_count = mid_left_count; + } else { + mid_track = mid_right; + mid_track_count = mid_right_count; + } + } + + // 车轮对应点(纯跟踪起始点) + float cx = UndistInverseMapW[(int) (IMAGE_H * 0.90f)][78]; + float cy = UndistInverseMapH[(int) (IMAGE_H * 0.90f)][78]; + + // 找最近点(起始点中线归一化) + float min_dist = 1e10; + + int begin_id = -1; + for (int i = 0; i < rpts_num; i++) { + float dx = rpts[i][1] - cx; + float dy = rpts[i][0] - cy; + float dist = sqrt(dx * dx + dy * dy); + if (dist < min_dist) { + min_dist = dist; + begin_id = i; + } + } + + if (begin_id >= 0 && rpts_num - begin_id >= 3){ + // 归一化中线 + rpts[begin_id][0] = cy; + rpts[begin_id][1] = cx; + rptsn_num = sizeof(rptsn) / sizeof(rptsn[0]); + GetLinesResample(rpts + begin_id, rpts_num - begin_id, rptsn, &rptsn_num, RESAMPLEDIST * PIXPERMETER ); + + // 远预锚点位置 + int aim_idx = clip(round(aim_distance / RESAMPLEDIST), 0, rptsn_num - 1); + + //近锚点位置 + int aim_idx_near = clip(round(0.25 / RESAMPLEDIST), 0, rptsn_num - 1); + + // 计算远锚点偏差值 + float dx = rptsn[aim_idx][1] - cx; + float dy = cy - rptsn[aim_idx][0] + 0.2 * PIXPERMETER; + float dn = sqrt(dx * dx + dy * dy); + //float error = -atan2f(dx, dy) * 180 / PI; + + // 计算近锚点偏差值 + float dx_near = rptsn[aim_idx_near][1] - cx; + float dy_near = cy - rptsn[aim_idx_near][0] + 0.2 * PIXPERMETER; + float dn_near = sqrt(dx_near * dx_near + dy_near * dy_near); + //float error_near = -atan2f(dx_near, dy_near) * 180 / PI; + + //考虑近点 + near_angle = -atanf(PIXPERMETER * 2 * 0.2 * dx_near / dn_near / dn_near) / PI * 180 ; + //考虑远点 + pure_angle = -atanf(PIXPERMETER * 2 * 0.2 * dx/ dn / dn) / PI * 180 ; + + + + } +} + diff --git a/app/gl_tracking.h b/app/gl_tracking.h new file mode 100644 index 0000000..e9f6cb3 --- /dev/null +++ b/app/gl_tracking.h @@ -0,0 +1,11 @@ +#ifndef TRACKING +#define TRACKING + + +void tracking(void); +void ElementJudge(void); +void ElementRun(void); +void MidLineTrack(void); + + +#endif /* STATE_H_ */ diff --git a/app/gl_transform_table.c b/app/gl_transform_table.c new file mode 100644 index 0000000..7850e2f --- /dev/null +++ b/app/gl_transform_table.c @@ -0,0 +1,26 @@ +#include "zf_common_headfile.h" +#include "gl_headfile.h" + + +float H_inv[3][3] = {}; + +// 逆变换,俯视->原图 +void transform(float X, float Y, int* x, int* y) { + // Apply inverse transformation + double p[3] = {X, Y, 1.0}; + double q[3] = {0.0, 0.0, 0.0}; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + q[i] += H_inv[i][j] * p[j]; + } + } + + *x =(int) (q[0] / q[2]); + *y = (int) (q[1] / q[2]); +} + + +const float UndistInverseMapH[90][140] = {}; + + +const float UndistInverseMapW[90][140] = {}; \ No newline at end of file diff --git a/app/gl_transform_table.h b/app/gl_transform_table.h new file mode 100644 index 0000000..e269262 --- /dev/null +++ b/app/gl_transform_table.h @@ -0,0 +1,14 @@ +#ifndef TRANSFORM_TABLE_H_ +#define TRANSFORM_TABLE_H_ + +#include "zf_common_headfile.h" + + +extern const float UndistInverseMapH[90][140] ; +extern const float UndistInverseMapW[90][140] ; +void transform(float X, float Y, int* x, int* y); + + +#endif /* TRANSFORM_TABLE_H_ */ + + diff --git a/app/main.c b/app/main.c index d71eb23..923401e 100644 --- a/app/main.c +++ b/app/main.c @@ -1,57 +1,170 @@ /********************************************************************************************************************* -* CH32V307VCT6 Opensourec Library CH32V307VCT6 Դ⣩һڹٷ SDK ӿڵĵԴ -* Copyright (c) 2022 SEEKFREE ɿƼ -* -* ļCH32V307VCT6 Դһ -* -* CH32V307VCT6 Դ -* Ըᷢ GPLGNU General Public License GNUͨù֤ -* GPL ĵ3棨 GPL3.0ѡģκκİ汾·/޸ -* -* Դķϣܷãδκεı֤ -* ûԻʺض;ı֤ -* ϸμ GPL -* -* ӦյԴͬʱյһ GPL ĸ -* ûУ -* -* ע -* Դʹ GPL3.0 Դ֤Э Ϊİ汾 -* Ӣİ libraries/doc ļµ GPL3_permission_statement.txt ļ -* ֤ libraries ļ ļµ LICENSE ļ -* ӭλʹò ޸ʱ뱣ɿƼİȨ -* -* ļ main -* ˾ ɶɿƼ޹˾ -* 汾Ϣ 鿴 libraries/doc ļ version ļ 汾˵ -* MounRiver Studio V1.8.1 -* ƽ̨ CH32V307VCT6 -* https://seekfree.taobao.com/ -* -* ޸ļ¼ -* ע -* 2022-09-15 W first version -********************************************************************************************************************/ + * CH32V307VCT6 Opensourec Library CH32V307VCT6 Դ⣩һڹٷ SDK ӿڵĵԴ + * Copyright (c) 2022 SEEKFREE ɿƼ + * + * ļCH32V307VCT6 Դһ + * + * CH32V307VCT6 Դ + * Ըᷢ GPLGNU General Public License GNUͨù֤ + * GPL ĵ3棨 GPL3.0ѡģκκİ汾·/޸ + * + * Դķϣܷãδκεı֤ + * ûԻʺض;ı֤ + * ϸμ GPL + * + * ӦյԴͬʱյһ GPL ĸ + * ûУ + * + * ע + * Դʹ GPL3.0 Դ֤Э Ϊİ汾 + * Ӣİ libraries/doc ļµ GPL3_permission_statement.txt ļ + * ֤ libraries ļ ļµ LICENSE ļ + * ӭλʹò ޸ʱ뱣ɿƼİȨ + * + * ļ main + * ˾ ɶɿƼ޹˾ + * 汾Ϣ 鿴 libraries/doc ļ version ļ 汾˵ + * MounRiver Studio V1.8.1 + * ƽ̨ CH32V307VCT6 + * https://seekfree.taobao.com/ + * + * ޸ļ¼ + * ע + * 2022-09-15 W first version + ********************************************************************************************************************/ #include "zf_common_headfile.h" +#include "gl_headfile.h" + +uint8 (*Img_Gray)[MT9V03X_W]; // ָ MT9V03X_W е uint8 ͵Ķάָ +//uint8 *mt9v03x_image_copy[0]; // ָ uint8 ͵һάָ +sint32 pts_left[PT_MAXLEN][2], pts_right[PT_MAXLEN][2]; +sint32 pts_left_count, pts_right_count; +float32 pts_inv_l[PT_MAXLEN][2], pts_inv_r[PT_MAXLEN][2]; +sint32 pts_inv_l_count, pts_inv_r_count; +float32 pts_filter_l[PT_MAXLEN][2], pts_filter_r[PT_MAXLEN][2]; +sint32 pts_filter_l_count, pts_filter_r_count; +float32 pts_resample_left[PT_MAXLEN][2], pts_resample_right[PT_MAXLEN][2]; +sint32 pts_resample_left_count, pts_resample_right_count; +float32 mid_left[PT_MAXLEN][2], mid_right[PT_MAXLEN][2]; +sint32 mid_left_count, mid_right_count; -int main (void) + +//ұ߾ֲǶȱ仯+Ǽֵ +float angle_new_left[PT_MAXLEN]; +float angle_new_right[PT_MAXLEN]; +int angle_new_left_num, angle_new_right_num; +uint8_t mt9v03x_image_copy[MT9V03X_H][MT9V03X_W]; + +// ұ߾ֲǶȱ仯 +float angle_left[PT_MAXLEN]; +float angle_right[PT_MAXLEN]; +int angle_left_num, angle_right_num; + +// Lǵ +int Lpt0_rpts0s_id, Lpt1_rpts1s_id; +bool Lpt0_found, Lpt1_found; +int Lpt1[2],Lpt0[2]; + +int Lpt_in0_rpts0s_id, Lpt_in1_rpts1s_id; +bool Lpt_in0_found, Lpt_in1_found; +int Lpt_in1[2], Lpt_in0[2]; + +// ֱ +bool is_straight0, is_straight1; + +// +bool is_turn0, is_turn1; + +// һ +float rptsn[PT_MAXLEN][2]; +int rptsn_num; +float aim_distance; + +enum track_type_e track_type = TRACK_RIGHT; + + +int frame_count = 0; + +void img_processing(); +void get_corners(); +void adaptiveThreshold(uint8_t* img_data, uint8_t* output_data, int width, int height, int block, uint8_t clip_value); +void threshold(uint8_t *img_data, uint8_t *output_data, int width, int height, int thres); + +int main(void) { - clock_init(SYSTEM_CLOCK_120M); // ʼоƬʱ ƵΪ 120MHz - debug_init(); // رڳʼMPU ʱ Դ - - // ˴дû ʼ + clock_init(SYSTEM_CLOCK_120M); // ʼоƬʱ ƵΪ 120MHz + debug_init(); // رڳʼMPU ʱ Դ ips114_init(); mt9v03x_init(); - // ˴дû ʼ - while(1) - { - // ˴дҪѭִеĴ - if(mt9v03x_finish_flag){ - ips114_show_gray_image(0, 0, mt9v03x_image[0], 188, 120, 188, 120,0); + while (1) { + //while (frame_count < 20) { + // if (mt9v03x_finish_flag) { + // memcpy(mt9v03x_image_copy[0], mt9v03x_image[0], (sizeof(mt9v03x_image_copy) / sizeof(uint8_t))); + // adaptiveThreshold((uint8_t*)mt9v03x_image_copy, (uint8_t*)mt9v03x_image_copy, 188, 120, 7, 8); + // //threshold((uint8_t*)mt9v03x_image_copy, (uint8_t*)mt9v03x_image_copy, MT9V03X_W, MT9V03X_H, 110); + // ips114_show_gray_image(0, 0, mt9v03x_image_copy[0], MT9V03X_W, MT9V03X_H, MT9V03X_W, MT9V03X_H, 0); + // mt9v03x_finish_flag = 0; + // frame_count++; + // } + + //} + if (mt9v03x_finish_flag) { + //ips114_show_gray_image(0, 0, mt9v03x_image[0], 188, 120, 188, 120,0); + memcpy(mt9v03x_image_copy[0], mt9v03x_image[0],(sizeof(mt9v03x_image_copy)/sizeof(uint8_t))); + //Img_Gray = mt9v03x_image; + //mt9v03x_image_copy[0] = Img_Gray[0]; + mt9v03x_finish_flag = 0; + + + state_type = COMMON_STATE; + img_processing(); + + get_corners(); + + aim_distance = COMMON_AIM; + + tracking(); + + ElementJudge(); + + ElementRun(); + + MidLineTrack(); + + } - // ˴дҪѭִеĴ + + } } + +/* +void threshold(uint8_t *img_data, uint8_t *output_data, int width, int height, int thres){ + for(int y=0; ythres ? 255 : 0; + } + } +} + + +void adaptiveThreshold(uint8_t* img_data, uint8_t* output_data, int width, int height, int block, uint8_t clip_value){ + int half_block = block / 2; + for(int y=half_block; ythres ? 255 : 0; + } + } +}*/ \ No newline at end of file diff --git a/app/main.h b/app/main.h new file mode 100644 index 0000000..ec7ba00 --- /dev/null +++ b/app/main.h @@ -0,0 +1,57 @@ +#ifndef MAIN_H +#define MAIN_H + +#include "zf_common_headfile.h" + + +//extern uint8 *mt9v03x_image_copy[0]; +extern sint32 pts_left[PT_MAXLEN][2], pts_right[PT_MAXLEN][2]; //0:H,1:W +extern sint32 pts_left_count, pts_right_count; +extern float32 pts_inv_l[PT_MAXLEN][2], pts_inv_r[PT_MAXLEN][2]; +extern sint32 pts_inv_l_count, pts_inv_r_count; +extern float32 pts_filter_l[PT_MAXLEN][2], pts_filter_r[PT_MAXLEN][2]; +extern sint32 pts_filter_l_count, pts_filter_r_count; +extern float32 pts_resample_left[PT_MAXLEN][2], pts_resample_right[PT_MAXLEN][2]; +extern sint32 pts_resample_left_count, pts_resample_right_count; +extern uint8_t mt9v03x_image_copy[MT9V03X_H][MT9V03X_W]; +extern float32 mid_left[PT_MAXLEN][2], mid_right[PT_MAXLEN][2]; +extern sint32 mid_left_count, mid_right_count; + + +extern float angle_left[PT_MAXLEN]; +extern float angle_right[PT_MAXLEN]; +extern int angle_left_num, angle_right_num; + + +extern float angle_new_left[PT_MAXLEN]; +extern float angle_new_right[PT_MAXLEN]; +extern int angle_new_left_num, angle_new_right_num; + + +extern int Lpt0_rpts0s_id, Lpt1_rpts1s_id; +extern bool Lpt0_found, Lpt1_found; +extern int Lpt1[2],Lpt0[2]; + +extern int Lpt_in0_rpts0s_id, Lpt_in1_rpts1s_id; +extern bool Lpt_in0_found, Lpt_in1_found; +extern int Lpt_in1[2], Lpt_in0[2]; + +extern bool is_straight0, is_straight1; + +extern bool is_turn0, is_turn1; + +extern float rptsn[PT_MAXLEN][2]; +extern int rptsn_num; +extern float aim_distance; + + + + +enum track_type_e { + TRACK_LEFT, + TRACK_RIGHT, +}; + +extern enum track_type_e track_type; + +#endif // MAIN_H \ No newline at end of file