当前位置:   article > 正文

智能车竞赛圆环、避障等元素方案开源_智能车如何找圆弧形拐点

智能车如何找圆弧形拐点

一、圆环

1.基于传统扫线的补线方法

   以右圆环为例

(1)找到近端右拐点,且左边界不丢线

 (2)找到右边中间拐点,定位近端右拐点,拉线

 (3)右边界底部丢线,结束拉线,找远端右拐点

 

 (4)定位远端右拐点,补线进环

 (5)编码器计步大于某阈值,停止补线,进普通循迹状态

  (6)赛道宽度突变,补线出环

 (7)找远端右拐点,补线不入环

 

 (8)结束,清空状态

  1. void Right_Roll_Judge(void)
  2. {
  3. extern int Distance_L;
  4. extern int Distance_R;
  5. int erro_x,erro_y;
  6. if(XK.roll_flag==0&&XK.roll_situation==0)//初始状态
  7. {
  8. if((Right_NearInflection_Judge(40,30)==1)&&(Left_Road_Lose(10,60)==1))//找到右拐点且左边界不丢失
  9. {
  10. XK.roll_situation=1;
  11. XK.roll_flag=1;
  12. XK.y3=28;
  13. erro_x=0;
  14. erro_y=0;
  15. XK.y2=0;
  16. XK.x2=0;
  17. }
  18. }
  19. if(XK.roll_situation==1)//找拐点,定位
  20. {
  21. Right_NearInflection_Catch(XK.y,60,XK.x,XK.y);//近拐点定位
  22. Right_RoundInflection_Catch(XK.y,1,XK.x2,XK.y2);//中间拐点定位
  23. if(XK.y>0&&XK.y2>0)//找到两个拐点,准备拉线
  24. {
  25. erro_x=0;
  26. erro_y=0;
  27. XK.y1=XK.y2;
  28. XK.x1=XK.x2;
  29. XK.roll_situation=2;
  30. }
  31. }
  32. if(XK.roll_situation==2)//拉线
  33. {
  34. Right_NearInflection_Catch((XK.y-2),60,XK.x2,XK.y2);
  35. erro_y=abs(XK.y2-20);
  36. XK.y3=XK.y;
  37. XK.y4=XK.y1+erro_y;
  38. XK.x3=XK.x;
  39. XK.x4=XK.x1;
  40. XK.line=1;
  41. if(XK.right_line[100]>160)//当右边界底部丢线,结束拉线
  42. {
  43. XK.line=0;
  44. XK.y2=0;
  45. XK.roll_situation=3;
  46. }
  47. }
  48. if(XK.roll_situation==3)//找远拐点
  49. {
  50. Right_FarInflection_Catch(1,40,XK.x2,XK.y2);//远拐点定位
  51. if((XK.y2>0)&&(XK.right_line[20]>150))//找到远拐点且右边界前端丢线,准备拉线
  52. {
  53. XK.y1=XK.y2;
  54. XK.x1=XK.x2;
  55. Distance_L=0;
  56. Distance_R=0;
  57. XK.Encoder_distance=0;
  58. XK.roll_situation=4;
  59. }
  60. }
  61. if(XK.roll_situation==4)//入环补线
  62. {
  63. XK.y3=25;
  64. XK.y4=55;
  65. XK.x3=110;
  66. XK.x4=45;
  67. XK.line=1;
  68. if(XK.Encoder_distance>5)//编码器计步(走一段距离,结束补线)
  69. {
  70. XK.y2=0;
  71. XK.line=0;
  72. Distance_L=0;
  73. Distance_R=0;
  74. XK.Encoder_distance=0;
  75. XK.roll_situation=6;
  76. }
  77. }
  78. if(XK.roll_situation==6)//环内状态
  79. {
  80. if((XK.road_width[29]-XK.road_width[30]>50)||XK.road_width[30]>150)//赛道宽度突变
  81. {
  82. XK.y1=XK.y2;
  83. XK.x1=XK.x2;
  84. XK.y2=0;
  85. Distance_L=0;
  86. Distance_R=0;
  87. XK.Encoder_distance=0;
  88. XK.roll_situation=7;
  89. }
  90. }
  91. if(XK.roll_situation==7)//出环补线
  92. {
  93. XK.y3=25;
  94. XK.y4=60;
  95. XK.x3=115;
  96. XK.x4=30;
  97. XK.line=1;
  98. Right_FarInflection_Catch(1,30,XK.x2,XK.y2);找远端拐点
  99. distence_count();
  100. if((XK.y2>0)&&XK.Encoder_distance>7)//不入环判断:在走一段距离的情况下,找到远端拐点
  101. {
  102. XK.y1=XK.y2;
  103. XK.x1=XK.x2;
  104. XK.roll_situation=8;
  105. }
  106. }
  107. if(XK.roll_situation==8)//不入环补线
  108. {
  109. XK.y3=100;
  110. XK.y4=20;
  111. XK.x3=136;
  112. XK.x4=113;
  113. XK.line=1;
  114. }
  115. if(XK.roll_situation==8)//不入环补线
  116. {
  117. Distance_L=0;
  118. Distance_R=0;
  119. XK.Encoder_distance=0;
  120. XK.y3=100;
  121. XK.y4=20;
  122. XK.x3=136;
  123. XK.x4=113;
  124. XK.line=1;
  125. }
  126. if((Left_Road_Lose(20,60)==1)&&XK.roll_situation==8)//右边界不丢失,圆环标志位清零
  127. {
  128. XK.roll_situation=0;
  129. XK.roll_flag=0;
  130. XK.line=0;
  131. }
  132. }
  133. void draw_line(void)//补线处理函数
  134. {
  135. if(XK.line==1)
  136. {
  137. ips114_add_line(XK.y,XK.x+0,XK.y1,XK.x1+0,0x00);
  138. ips114_add_line(XK.y,XK.x+1,XK.y1,XK.x1+1,0x00);
  139. ips114_add_line(XK.y,XK.x+2,XK.y1,XK.x1+2,0x00);
  140. ips114_add_line(XK.y,XK.x+3,XK.y1,XK.x1+3,0x00);
  141. ips114_add_line(XK.y,XK.x-1,XK.y1,XK.x1-1,0x00);
  142. ips114_add_line(XK.y,XK.x-2,XK.y1,XK.x1-2,0x00);
  143. }
  144. }

关于如何在图像数组中补线,基于逐飞的IPS114画线函数更改即可

  1. void ips114_add_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color)
  2. {
  3. int16 x_dir = (x_start<x_end ? 1:-1);
  4. int16 y_dir = (y_start<y_end ? 1:-1);
  5. float temp_rate = 0;
  6. float temp_b = 0;
  7. if(x_start != x_end)
  8. {
  9. temp_rate = (float)(y_start-y_end)/(float)(x_start-x_end);
  10. temp_b = (float)y_start-(float)x_start*temp_rate;
  11. }
  12. else
  13. {
  14. while(y_start != y_end)
  15. {
  16. mt9v03x_image_copy[x_start][ y_start]=0x00;//根据需要更改的图像数组
  17. y_start += y_dir;
  18. }
  19. return;
  20. }
  21. if(abs(y_start-y_end)>abs(x_start-x_end))
  22. {
  23. while(y_start != y_end)
  24. {
  25. mt9v03x_image_copy[x_start][ y_start]=0x00;//根据需要更改的图像数组
  26. y_start += y_dir;
  27. x_start = (int16)(((float)y_start-temp_b)/temp_rate);
  28. }
  29. }
  30. else
  31. {
  32. while(x_start != x_end)
  33. {
  34. mt9v03x_image_copy[x_start][ y_start]=0x00;//根据需要更改的图像数组
  35. x_start += x_dir;
  36. y_start = (int16)((float)x_start*temp_rate+temp_b);
  37. }
  38. }
  39. }
2.电磁圆环,摄像头辅助判断
  1. void elec_roll_judge(void)
  2. {
  3. // ********* 摄像头区分左右环(这一段可单独放在图像处理函数里) ***********
  4. if(XK.roll_flag==1&&XK.roll_situation==1)
  5. {
  6. XK.rolldirr=rroll_dir_judge(10,50,65);
  7. XK.rolldirl=lroll_dir_judge(10,50,65);
  8. }
  9. // *****************************************************************
  10. extern float AD[6];
  11. if(XK.roll_flag==0&&XK.roll_situation==0)
  12. {
  13. if(AD[1]>3000&&AD[0]>3000)//中间电感大于一定阈值
  14. {
  15. XK.roll_flag=1;
  16. XK.roll_situation=1;
  17. Distance_L=0;
  18. Distance_R=0;
  19. XK.Encoder_distance=0;
  20. }
  21. }
  22. if(XK.roll_flag==1&&XK.roll_situation==1)
  23. {
  24. if(XK.rolldirr==1)//右圆环状态
  25. {
  26. XK.roll_flagr=1;
  27. XK.roll_flagl=0;
  28. XK.roll_situation=2;
  29. Distance_L=0;
  30. Distance_R=0;
  31. XK.Encoder_distance=0;
  32. }
  33. else if(XK.rolldirl==1)//左圆环状态
  34. {
  35. XK.roll_flagr=0;
  36. XK.roll_flagl=1;
  37. XK.roll_situation=2;
  38. Distance_L=0;
  39. Distance_R=0;
  40. XK.Encoder_distance=0;
  41. }
  42. if(XK.Encoder_distance>15)//计步大于某值,跳出圆环
  43. {
  44. XK.roll_situation=0;
  45. XK.roll_flag=0;
  46. XK.roll_flagl=0;
  47. XK.roll_flagr=0;
  48. Distance_L=0;
  49. Distance_R=0;
  50. XK.Encoder_distance=0;
  51. }
  52. }
  53. if(XK.roll_flag==1&&XK.roll_situation==2)
  54. {
  55. if(XK.roll_flagl==1&&XK.roll_flagr==0)//右圆环状态
  56. {
  57. if(AD[3]>3300)//右斜电感大于阈值,舵机打角
  58. {
  59. XK.roll_situation=3;
  60. Distance_L=0;
  61. Distance_R=0;
  62. XK.Encoder_distance=0;
  63. }
  64. }
  65. if(XK.roll_flagl==0&&XK.roll_flagr==1)//左圆环状态
  66. {
  67. if(AD[4]>3400)//左斜电感大于阈值,舵机打角
  68. {
  69. XK.roll_situation=3;
  70. Distance_L=0;
  71. Distance_R=0;
  72. XK.Encoder_distance=0;
  73. }
  74. }
  75. }
  76. if(XK.roll_flag==1&&XK.roll_situation==3)//环内状态
  77. {
  78. if(XK.Encoder_distance>9)//计步
  79. {
  80. XK.roll_situation=5;
  81. Distance_L=0;
  82. Distance_R=0;
  83. XK.Encoder_distance=0;
  84. }
  85. }
  86. if(XK.roll_flag==1&&XK.roll_situation==5)
  87. {
  88. if(XK.roll_flagl==1&&XK.roll_flagr==0)//右圆环出环判断
  89. {
  90. if(AD[5]>1700)//右侧电感大于某阈值,右打角
  91. {
  92. XK.roll_situation=6;
  93. Distance_L=0;
  94. Distance_R=0;
  95. XK.Encoder_distance=0;
  96. }
  97. }
  98. if(XK.roll_flagl==0&&XK.roll_flagr==1)//左圆环出环判断
  99. {
  100. if(AD[2]>2800)//左侧电感大于某阈值,左打角
  101. {
  102. XK.roll_situation=6;
  103. Distance_L=0;
  104. Distance_R=0;
  105. XK.Encoder_distance=0;
  106. }
  107. }
  108. }
  109. if(XK.roll_flag==1&&XK.roll_situation==6)//计步大于某阈值,结束圆环,标志位清零
  110. {
  111. if(XK.Encoder_distance>3)
  112. {
  113. XK.roll_situation=0;
  114. XK.roll_flag=0;
  115. XK.roll_flagr=0;
  116. XK.roll_flagl=0;
  117. Distance_L=0;
  118. Distance_R=0;
  119. XK.Encoder_distance=0;
  120. }
  121. }
  122. }

二、避障

 这里需要用到编码器计行驶圈数

  1. #define ENCORDER_PRCISION 1024.f //512线、1024线等
  2. #define ENCORDER_D 19.2f //编码器齿轮直径 齿数30
  3. #define WHEEL_D 64.0f //车轮直径
  4. #define WHEEL_GEAR_D 41.0f //车轮直连齿轮直径 齿数 68
  5. #define GET_DISTANCE_M(val) ((((val/ENCORDER_PRCISION)*ENCORDER_D*PI )*WHEEL_D)/WHEEL_GEAR_D/1000)
  6. void distence_count(void)
  7. {
  8. Distance_L = Distance_L + XK.speedl;
  9. Distance_R = Distance_R + XK.speedr;
  10. XK.Encoder_distance=GET_DISTANCE_M((Distance_L + Distance_R) / 2);
  11. }

  1. void barrier (void)
  2. {
  3. extern int Distance_L;//左轮距
  4. extern int Distance_R;//右轮距
  5. if(dl1a_distance_mm<XK.dis1&&XK.barrier_judge==0)//避障预判断
  6. {
  7. Gyro_qin0();//陀螺仪数值清零
  8. XK.barrier_in=1;//避障状态
  9. XK.barrier_judge=1;//避障进入标志位
  10. XK.Encoder_distance=0;//测距距离
  11. }
  12. if(XK.barrier_judge==1)
  13. {
  14. switch (XK.barrier_in)
  15. {
  16. case 1:
  17. {
  18. if(dl1a_distance_mm<=XK.dis2)//行进距离
  19. {
  20. if((mt9v03x_image[2][94]+mt9v03x_image[3][94]+mt9v03x_image[3]
  21. [93]+mt9v03x_image[3][95])/4<55)//tof测距小于某阈值且图像灰度像素小于某阈值
  22. (区分坡道与避障)
  23. {
  24. Distance_L=0;
  25. Distance_R=0;
  26. XK.Encoder_distance=0;
  27. XK.barrier_in=2;
  28. Gyro_qin0();
  29. wireless_uart_send_string("6");//与后车通信
  30. }
  31. else//未达条件跳出状态
  32. {
  33. Distance_L=0;
  34. Distance_R=0;
  35. XK.time=0;
  36. XK.Encoder_distance=0;
  37. XK.barrier_in=0;
  38. XK.barrier_judge=0;
  39. Gyro_qin0();
  40. }
  41. }
  42. }
  43. break;
  44. case 2://打角避障
  45. {
  46. if(XK.dash_dir==1)//右边避障
  47. {
  48. if(eulerAngle.yaw<-3.1)//右航向角
  49. {
  50. Distance_L=0;
  51. Distance_R=0;
  52. XK.time=0;
  53. XK.Encoder_distance=0;
  54. XK.barrier_in=3;
  55. Gyro_qin0();//陀螺仪数值清零
  56. }
  57. }
  58. if(XK.dash_dir==0)//左边避障
  59. {
  60. if(eulerAngle.yaw>1.6)//左航向角
  61. {
  62. Distance_L=0;
  63. Distance_R=0;
  64. XK.time=0;
  65. XK.Encoder_distance=0;
  66. XK.barrier_in=3;
  67. Gyro_qin0();//陀螺仪数值清零
  68. }
  69. }
  70. }
  71. break;
  72. case 3://直行
  73. {
  74. distence_count();//编码器测距
  75. if(XK.Encoder_distance>3)//行进距离
  76. {
  77. Distance_L=0;
  78. Distance_R=0;
  79. XK.time=0;
  80. XK.Encoder_distance=0;
  81. XK.barrier_in=4;
  82. Gyro_qin0();
  83. }
  84. }
  85. break;
  86. case 4://打角
  87. {
  88. if(XK.dash_dir==1)//左边避障
  89. {
  90. if(eulerAngle.yaw>3.6)//左航向角
  91. {
  92. Distance_L=0;
  93. Distance_R=0;
  94. XK.time=0;
  95. XK.Encoder_distance=0;
  96. XK.barrier_in=5;
  97. Gyro_qin0();
  98. }
  99. }
  100. if(XK.dash_dir==0)//右边避障
  101. {
  102. if(eulerAngle.yaw<-6.0)//右航向角
  103. {
  104. Distance_L=0;
  105. Distance_R=0;
  106. XK.time=0;
  107. XK.Encoder_distance=0;
  108. XK.barrier_in=5;
  109. Gyro_qin0();
  110. }
  111. }
  112. }
  113. break;
  114. case 5://直行
  115. {
  116. distence_count();//编码器测距
  117. if(XK.Encoder_distance>1)//行进距离
  118. {
  119. Distance_L=0;
  120. Distance_R=0;
  121. XK.time=0;
  122. XK.Encoder_distance=0;
  123. XK.barrier_in=6;
  124. Gyro_qin0();
  125. }
  126. }
  127. break;
  128. case 6://打角
  129. {
  130. if(XK.dash_dir==1)//左边避障
  131. {
  132. if(eulerAngle.yaw>5.0)//左航向角
  133. {
  134. Distance_L=0;
  135. Distance_R=0;
  136. XK.time=0;
  137. XK.Encoder_distance=0;
  138. XK.barrier_in=7;
  139. Gyro_qin0();
  140. }
  141. }
  142. if(XK.dash_dir==0)//右边避障
  143. {
  144. if(eulerAngle.yaw<-5.9)//右航向角
  145. {
  146. Distance_L=0;
  147. Distance_R=0;
  148. XK.time=0;
  149. XK.Encoder_distance=0;
  150. XK.barrier_in=7;
  151. Gyro_qin0();
  152. }
  153. }
  154. }
  155. break;
  156. case 7://直行,回赛道
  157. {
  158. extern float AD[6];
  159. distence_count();//编码器测距
  160. if(XK.dash_dir==1)
  161. {
  162. if((mt9v03x_image[110][140]+mt9v03x_image[110][141]+mt9v03x_image[110]
  163. [139])/3>100)//图像灰度像素大于某阈值(白色赛道)
  164. {
  165. Distance_L=0;
  166. Distance_R=0;
  167. XK.time=0;
  168. XK.Encoder_distance=0;
  169. XK.barrier_in=0;
  170. XK.barrier_judge=0;
  171. }
  172. }
  173. if(XK.dash_dir==0)
  174. {
  175. if((mt9v03x_image[110][48]+mt9v03x_image[110][49]+mt9v03x_image[110]
  176. [50])/3>100)//图像灰度像素大于某阈值(白色赛道)
  177. {
  178. Distance_L=0;
  179. Distance_R=0;
  180. XK.time=0;
  181. XK.Encoder_distance=0;
  182. XK.barrier_in=0;
  183. XK.barrier_judge=0;
  184. }
  185. }
  186. }
  187. break;
  188. }
  189. }
  190. }

本文旨在本校智能车实验室教学,若有错漏,欢迎指正

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/420585
推荐阅读
相关标签
  

闽ICP备14008679号