没有用PID算法的

  1. void getABCD()
  2. { //获取4、5、6、7号灯值
  3. val4 = 0;
  4. val5 = 0;
  5. val6 = 0;
  6. val7 = 0;
  7. int i;
  8. for (i = 0; i < 4; i++) { //读取四次减小误差
  9. val4 += analogRead(QI4);
  10. val5 += analogRead(QI5);
  11. val7 += analogRead(HI4);
  12. val6 += analogRead(HI5);
  13. }
  14. val4 = val4 / 4;
  15. val5 = val5 / 4;
  16. val6 = val6 / 4;
  17. val7 = val7 / 4;
  18. }
  19. int change = 40 ;
  20. void yanxianzou(int speeda, int speedb) {//沿线走
  21. int average = 1500;
  22. //(QvalueMax + QvalueMin )/2,这是经过测试之后的灰度传感器在黑线上的最大值最小值
  23. getABCD();
  24. //调用灰度
  25. if (val4 < average && val5 < average ) { //全黑
  26. goStraight(speeda,speedb);
  27. }
  28. if (val4 < average && val5 > average) { //偏右
  29. goStraight(speeda + change ,speedb - change );
  30. }//右轮加速,左轮减速
  31. if (val4 > average && val5 < average) { //偏左
  32. goStraight(speeda - change ,speedb + change );
  33. }//右轮减速,左轮加速
  34. if (val4 > average && val5 > average) { //全白
  35. goStraight(speeda,speedb);
  36. }//右轮保持,左轮保持

用PID算法的需要测试val的值

  1. void getABCD()
  2. { //获取4、5、6、7号灯值
  3. val4 = 0;
  4. val5 = 0;
  5. val6 = 0;
  6. val7 = 0;
  7. int i;
  8. for (i = 0; i < 4; i++) {
  9. val4 += analogRead(QI4);
  10. val5 += analogRead(QI5);
  11. val7 += analogRead(HI4);
  12. val6 += analogRead(HI5);
  13. }
  14. val4 = val4 / 4;
  15. val5 = val5 / 4;
  16. val6 = val6 / 4;
  17. val7 = val7 / 4;
  18. }
  19. void Sbigcircle(int speeda , int speedb )//顺时针走大圆
  20. {
  21. getABCD();
  22. int average = (QvalueMax + QvalueMin)/2 ;//1850 //注意写一下最大值是怎么获得的
  23. P_error1 = val4 - average ;
  24. if(P_error1 < 0)
  25. P_error1 = 0 ;
  26. // D_error1 = P_error1 - D_error1 ; //这里的d和i就不调了
  27. // I_error1 += P_error1 ;
  28. P_error2 = val5 - average ;
  29. if(P_error2 < 0)
  30. P_error2 = 0 ;
  31. //D_error2 = P_error2 - D_error2 ;
  32. //I_error2 += P_error2 ;
  33. if(val4 < average + 1000 && val5 < average ) //这里需要改
  34. {
  35. I_error1 = 0 ;
  36. I_error2 = 0 ;
  37. }
  38. double tem = 0.8 * Kp1;
  39. if(val4 < 600 && val5 < 600)
  40. goStraight(speeda - 10 ,speedb + 25);
  41. else if(val4 < 1000 && val5 > 2000)//偏右 1.3倍Kp稳定
  42. goStraight(speeda + Kp1 *P_error1 + Ki1 * I_error1+ Kd1 *D_error1 ,speedb - Kp1 *P_error2 - Ki1 * I_error2 - Kd1 *D_error2 );
  43. else if(val4 > 2000 && val5 < 1000 )//偏左
  44. goStraight(speeda - Kp1 *P_error1 - Ki1 * I_error1 - Kd1 *D_error1 - 10 ,speedb + Kp1 *P_error2 + Ki1 * I_error2 + Kd1 *D_error2 + 25);
  45. else
  46. goStraight(speeda - 10 ,speedb + 25 );//25
  47. }

PID改进版

  1. /循迹
  2. const float Kp1 = 13;// Ki1 = 0.25, Kd1 = 1.5; //pid前进参数参数
  3. //const float Kp2 = 11, Ki2 = 0.2, Kd2 = 4.5; //pid后退参数参数
  4. float error = 0, P = 0,;//I = 0, D = 0,
  5. float PID_value = 0;
  6. float previous_error = 0;// previous_I = 0;
  7. void getABCD()
  8. { //获取4、5、6、7号灯值
  9. val4 = 0;
  10. val5 = 0;
  11. val6 = 0;
  12. val7 = 0;
  13. int i = 0;
  14. ///滤波
  15. for (i = 0; i < 4; i++) {
  16. val4 += analogRead(Qvalue4);
  17. val5 += analogRead(Qvalue5);
  18. val6 += analogRead(Hvalue4);
  19. val7 += analogRead(Hvalue5);
  20. }
  21. val4 = val4 / 4;
  22. val5 = val5 / 4;
  23. val6 = val6 / 4;
  24. val7 = val7 / 4;
  25. if (flag == 1) {//前进flag设为1 //就是说第一种方向行进时的偏差
  26. if (val4 < 800 && val5 < 600)//在黑线
  27. error = 0;
  28. else if (val4 < 800 && val5 > 600)//偏右
  29. error = 3;
  30. else if (val4 > 800&& val5 < 600)//偏左
  31. error = 3;
  32. else
  33. error = 0;
  34. }
  35. //写一个另外几种方向行进时的偏差
  36. //else {//后退
  37. if (val6 < 600 && val7 <1000)//在黑线
  38. error = 0;
  39. else if (val6 < 600 && val7 > 1000)//偏右
  40. error = 3;
  41. else if (val6 > 600 && val7 < 1000)//偏左
  42. error = 3;
  43. else
  44. error = 0;
  45. }
  46. }
  47. void calc_pid() {
  48. P = error;
  49. //I = I + error;
  50. //D = error - previous_error;
  51. if(flag == 1)
  52. {
  53. if (I > 30) I = 10;
  54. PID_value = (Kp1 * P) + (Ki1 * I) + (Kd1* D);
  55. }
  56. else
  57. {
  58. if (I > 25) I = 15;
  59. PID_value = (Kp2 * P) + (Ki2 * I) + (Kd2* D);
  60. }
  61. previous_error = error;
  62. }
  63. void yanxianzou(int a, int b) {
  64. flag = 1;
  65. getABCD();
  66. calc_pid();
  67. if (val4 < 1000 && val5 < 900)//在黑线
  68. goStraight(a, b);
  69. else if (val4 < 1000 && val5 > 900)//偏右
  70. goStraight(a + PID_value, b - PID_value);
  71. else if (val4 > 1000&& val5 < 900)//偏左
  72. goStraight(a - PID_value, b + PID_value);
  73. else
  74. goStraight(a, b);
  75. }
  76. /*void yanxiantui(int a, int b) {
  77. flag = 0;
  78. getABCD();
  79. calc_pid();
  80. if (val6 < 800 && val7 <1400)//在黑线
  81. retreat(a, b);
  82. else if (val6 > 800 && val7 < 1400)//偏左
  83. retreat(a - PID_value, b +PID_value);
  84. else if (val6 < 800 && val7 > 1400)//偏右
  85. retreat(a+PID_value , b - PID_value);
  86. else
  87. retreat(a, b);
  88. }
  89. */