|
发表于 2012-10-22 09:05:26
|
显示全部楼层
风烟雨风 发表于 2012-10-20 16:37
我的情况跟你差不多,车轮转一圈大约700个脉冲,然后我是记700次,采样周期是20ms.
现在主要情况是我使用 ...
可能我們的做法還是有差異。
PID我分為兩部份 一部份計算控制小車的前進速度的pwm ,一部份做左右輪子平衡的pwm,我記得大概前進的時候是一般是在±4內波動,因為我是用累積的,所以沒有誤差積分。
但是這個情況下不一定能走直,想了好久,加了一個平衡誤差的虛參數,終於走直線了。見一下部份代碼
if(motion)
{
pwm = IncPIDCalc(&SPEED,(LDelta+RDelta)/2); //小车恒定速度计算
switch(motion){
case FORWARD:dSPEED.SetPoint = 0x00; //DIF是纠正参数 ,在小车前进或后退,没有传感器的状况下为保证
dTotal = TotalCntL*DIFF- TotalCntR; //运动路径为直线,必须做平衡去掉机械误差
//dTotal = TotalCntL*Line- TotalCntR;
dtpwm = dtIncPIDCalc(&dSPEED,dTotal/8);break; //切此处用的速度计算是使用当前计数总和减去上一次计数总和,避免误差的累积
case REVERSE:dSPEED.SetPoint = 0x00;
dTotal = TotalCntL*DIFR- TotalCntR; //DIF是纠正参数
dtpwm = dtIncPIDCalc(&dSPEED,dTotal/8);break;
default:
dTotal = TotalCntL- TotalCntR;
dSpd = LDelta-RDelta; //左右转速差值
dtpwm = dtIncPIDCalc(&dSPEED,dSpd);break;
}
Lpwm = pwm+dtpwm; //恒定速度控制+差分速度控制
if(Lpwm>250)Lpwm = 250; //小车PWM的控制范围为0-250 所以要做限制
if(Lpwm<0)Lpwm = 0;
Rpwm = pwm-dtpwm;
if(Rpwm>250)Rpwm = 250;
if(Rpwm<0)Rpwm = 0; //使能H桥
HB = 1;
}
if(!(motion&0x0f))
HB = 0;//如果不在运动状态就把H桥进入休眠,避免电机狂转
…… |
|