void PID_test() //使用于寻迹小车,//根据灰度传感器返回值,判断小车是否歪斜,进而调整速度使小车摆正,但是四个麦轮控制速度协调太难了//调整速度的正负号需要再仔细看一下{int PID_LEVEL_1=7, //根据转弯幅度设置的三个值 PID_LEVEL_2=8, PID_LEVEL_3=10;//定义了三个PID的模式//PID直线前进循迹 int count=0; //防止第二次调用时速度过快 float error=0; static float lasterror=0; float kp=100;//决定每次调节幅度的大小,数值越大调节幅度越大 float ki=0.0f; float kd=10; //可以决定调节速度的快慢,数值越大调节速度越快,当以比例为主的时候. 可以起到修正作用 float derivative=0; //导数 static float iout=0; float pid=0; if(Condition!=-1) { Call(); switch(Condition) { //-----------------------------直行-------------------------------// case 0: //0 1 2 3 4 5//直行 int a; a=((Glevel[0]<<5)(GLevel[1] << 4) | (GLevel[2] << 3) | (GLevel[3] << 2) | (GLevel[4]<<1) | (GLevel[5])); switch(a) //这里的灰度全反了,检测到黑线是1,白色是0 { // case 0x35://左小偏 只有2能检测到 //110111 error=-PID_LEVEL_2; break; case 0x3B://右小偏 只有3能检测到 //111011 error=PID_LEVEL_2; break; case 0x33://直行不偏转 //110011 error=0; break; case 0x39://左中偏 3,4能够检测到 //111001 error=PID_LEVEL_2+1; break; case 0x27://右中偏 1 2能够检测到 //100111 error=-PID_LEVEL_2; break; case 0x3C://左大偏 右侧灰度检测到 4,5能够检测到 //111100 error=PID_LEVEL_3+1; break; case 0x0F://右大偏 0,1 能够检测到 //001111 error=-PID_LEVEL_3+1; break; default: error=0; break; }//switch(a) //------------------------------------后退-----------------------------// case 1://后退 { //灰度传感器损坏暂时不写 } //--------------------------------------左横行---------------------------// case 2://左横行 //12~16为左,17~21为右,左右两边小数在前,大数在后 //12,13,14,15,16 if(GLevel[14]==1)//当中间的传感器没有检测到黑线的时候 { count=1000; LEFT=100; RIGHT=100; } else if(count>0&&GLevel[14]==0)//当中间的两个传感器检测到黑线的时候, { count--; delay_ms(1); LEFT=pwm_left/8;//这里的LEft需要改--------------------------------------------------- RIGHT=pwm_right/8;//这里的RIGHT需要改-------------------------------------------------- } int a; a=((GLevel[12] << 3) | (GLevel[13] << 2) | (GLevel[15] << 1) | (GLevel[16])); switch(a) { case 0x08: //1000 error=PID_LEVEL_2; break; case 0x01: //0001 error=-PID_LEVEL_2; break; case 0x00: // 0000 error=0; break; case 0x06: // 0110 error=0; break; case 0x09: // 1001 error=0; break; case 0x0D: // 1101 error=PID_LEVEL_1+1; break; case 0x0C: // 1100 error=PID_LEVEL_2+1; break; case 0x0E: // 1110 error=PID_LEVEL_3+1; break; case 0x0B: //1011 error=-PID_LEVEL_1; break; case 0x03: // 0011 error=-PID_LEVEL_2; break; case 0x07: // 0111 error=-PID_LEVEL_3; break; default: error=0; break; } case 3://右横行{ if(GLevel[19]==1)//当中间的传感器没有检测到黑线的时候 { count=1000; LEFT=100; RIGHT=100; } if(count>0&&GLevel[19]==0)//当中间的两个传感器检测到黑线的时候, { count--; delay_ms(1); LEFT=pwm_left/8;//这里的LEft需要改--------------------------------------------------- RIGHT=pwm_right/8;//这里的RIGHT需要改-------------------------------------------------- } //12~16为左,17~21为右,左右两边小数在前,大数在后 //17,18,19,20,21 int a; a=((GLevel[17] << 3) | (GLevel[18] << 2) | (GLevel[19] << 1) | (GLevel[20])); switch(a) { case 0x08: //1000 error=PID_LEVEL_2; break; case 0x01: //0001 error=-PID_LEVEL_2; break; case 0x00: // 0000 error=0; break; case 0x06: // 0110 error=0; break; case 0x09: // 1001 error=0; break; case 0x0D: // 1101 error=PID_LEVEL_1+1; break; case 0x0C: // 1100 error=PID_LEVEL_2+1; break; case 0x0E: // 1110 error=PID_LEVEL_3+1; break; case 0x0B: //1011 error=-PID_LEVEL_1; break; case 0x03: // 0011 error=-PID_LEVEL_2; break; case 0x07: // 0111 error=-PID_LEVEL_3; break; default: error=0; break; } } }//switch(Condition) } //float LEFT=pwm_left; //float RIGHT=pwm_right; lasterror=error; //示例:如果直行左中偏(车在黑线的左侧),error就是正值,左侧加正值,右侧减正值 iout += ki *error; derivative=error-lasterror; pid=kp*error+kd*derivative+ki*iout; pid=pid/10; // Chassis_Control((LEFT+pid),(RIGHT-pid)); }