没有用PID算法的
void getABCD(){ //获取4、5、6、7号灯值 val4 = 0; val5 = 0; val6 = 0; val7 = 0; int i; for (i = 0; i < 4; i++) { //读取四次减小误差 val4 += analogRead(QI4); val5 += analogRead(QI5); val7 += analogRead(HI4); val6 += analogRead(HI5); } val4 = val4 / 4; val5 = val5 / 4; val6 = val6 / 4; val7 = val7 / 4;}int change = 40 ;void yanxianzou(int speeda, int speedb) {//沿线走 int average = 1500; //(QvalueMax + QvalueMin )/2,这是经过测试之后的灰度传感器在黑线上的最大值最小值 getABCD(); //调用灰度 if (val4 < average && val5 < average ) { //全黑 goStraight(speeda,speedb); } if (val4 < average && val5 > average) { //偏右 goStraight(speeda + change ,speedb - change ); }//右轮加速,左轮减速 if (val4 > average && val5 < average) { //偏左 goStraight(speeda - change ,speedb + change ); }//右轮减速,左轮加速 if (val4 > average && val5 > average) { //全白 goStraight(speeda,speedb); }//右轮保持,左轮保持
用PID算法的需要测试val的值
void getABCD(){ //获取4、5、6、7号灯值 val4 = 0; val5 = 0; val6 = 0; val7 = 0; int i; for (i = 0; i < 4; i++) { val4 += analogRead(QI4); val5 += analogRead(QI5); val7 += analogRead(HI4); val6 += analogRead(HI5); } val4 = val4 / 4; val5 = val5 / 4; val6 = val6 / 4; val7 = val7 / 4;}void Sbigcircle(int speeda , int speedb )//顺时针走大圆{ getABCD(); int average = (QvalueMax + QvalueMin)/2 ;//1850 //注意写一下最大值是怎么获得的 P_error1 = val4 - average ; if(P_error1 < 0) P_error1 = 0 ; // D_error1 = P_error1 - D_error1 ; //这里的d和i就不调了 // I_error1 += P_error1 ; P_error2 = val5 - average ; if(P_error2 < 0) P_error2 = 0 ; //D_error2 = P_error2 - D_error2 ; //I_error2 += P_error2 ; if(val4 < average + 1000 && val5 < average ) //这里需要改 { I_error1 = 0 ; I_error2 = 0 ; } double tem = 0.8 * Kp1; if(val4 < 600 && val5 < 600) goStraight(speeda - 10 ,speedb + 25); else if(val4 < 1000 && val5 > 2000)//偏右 1.3倍Kp稳定 goStraight(speeda + Kp1 *P_error1 + Ki1 * I_error1+ Kd1 *D_error1 ,speedb - Kp1 *P_error2 - Ki1 * I_error2 - Kd1 *D_error2 ); else if(val4 > 2000 && val5 < 1000 )//偏左 goStraight(speeda - Kp1 *P_error1 - Ki1 * I_error1 - Kd1 *D_error1 - 10 ,speedb + Kp1 *P_error2 + Ki1 * I_error2 + Kd1 *D_error2 + 25); else goStraight(speeda - 10 ,speedb + 25 );//25}
PID改进版
/循迹const float Kp1 = 13;// Ki1 = 0.25, Kd1 = 1.5; //pid前进参数参数 //const float Kp2 = 11, Ki2 = 0.2, Kd2 = 4.5; //pid后退参数参数 float error = 0, P = 0,;//I = 0, D = 0, float PID_value = 0; float previous_error = 0;// previous_I = 0;void getABCD(){ //获取4、5、6、7号灯值 val4 = 0; val5 = 0; val6 = 0; val7 = 0; int i = 0; ///滤波 for (i = 0; i < 4; i++) { val4 += analogRead(Qvalue4); val5 += analogRead(Qvalue5); val6 += analogRead(Hvalue4); val7 += analogRead(Hvalue5); } val4 = val4 / 4; val5 = val5 / 4; val6 = val6 / 4; val7 = val7 / 4; if (flag == 1) {//前进flag设为1 //就是说第一种方向行进时的偏差 if (val4 < 800 && val5 < 600)//在黑线 error = 0; else if (val4 < 800 && val5 > 600)//偏右 error = 3; else if (val4 > 800&& val5 < 600)//偏左 error = 3; else error = 0; } //写一个另外几种方向行进时的偏差 //else {//后退 if (val6 < 600 && val7 <1000)//在黑线 error = 0; else if (val6 < 600 && val7 > 1000)//偏右 error = 3; else if (val6 > 600 && val7 < 1000)//偏左 error = 3; else error = 0; }}void calc_pid() { P = error; //I = I + error; //D = error - previous_error; if(flag == 1) { if (I > 30) I = 10; PID_value = (Kp1 * P) + (Ki1 * I) + (Kd1* D); } else { if (I > 25) I = 15; PID_value = (Kp2 * P) + (Ki2 * I) + (Kd2* D); } previous_error = error;}void yanxianzou(int a, int b) { flag = 1; getABCD(); calc_pid(); if (val4 < 1000 && val5 < 900)//在黑线 goStraight(a, b); else if (val4 < 1000 && val5 > 900)//偏右 goStraight(a + PID_value, b - PID_value); else if (val4 > 1000&& val5 < 900)//偏左 goStraight(a - PID_value, b + PID_value); else goStraight(a, b);}/*void yanxiantui(int a, int b) { flag = 0; getABCD(); calc_pid(); if (val6 < 800 && val7 <1400)//在黑线 retreat(a, b); else if (val6 > 800 && val7 < 1400)//偏左 retreat(a - PID_value, b +PID_value); else if (val6 < 800 && val7 > 1400)//偏右 retreat(a+PID_value , b - PID_value); else retreat(a, b);}*/