让小车到达指定位置有哪些PID算法?
许多学生不知道PID是什么,因为许多学生不是自动化的。他们需要信息和程序来开口说话。很明显,这种学习方法是错误的。至少,首先,您需要理解PID是什么。首先,我们为什么要做PID?由于外部原因,汽车的实际速度有时是不稳定的。一是要使汽车在最快的时间内达到既定的目标速度,二是要使汽车在最短的时间内达到既定的目标速度。速度控制系统采用闭环控制,以满足整个系统的稳定性要求。
速度是系统参数之一。这是第三次。汽车的速度调节肯定不是线性的,有这么多的外部因素,没有人能证明它是线性的。如果它是线性的,就用P。例如,当PWM=60%时,速度是2m/S,所以如果你想要3M/S,你可以把PWM增加到90%。因为90/60=3/2,这太多了。完美无缺。那么它不是线性的,如何控制PWM来达到预期的速度呢?我们应该迅速、准确和无情。(即快速和准无情)系统的速度调节过程必须用一种算法来调节,这就是通常所说的PID算法。自动。控制系统的被控对象变化很大,必须改变PID参数才能满足系统的性能要求。这给用户,特别是初学者带来了很大的麻烦。
下面简要介绍调试PID参数的一般步骤:
1.负反馈。自动控制理论又称负反馈控制理论。首先,对系统的接线进行检查,以确定系统的反馈为负。例如,在电机调速系统中,当电机处于正旋转(PID算法中的误差=输入-反馈)时,输入信号为正,反馈信号为正,而电机同时处于正旋转。速度越高,反馈信号越大。其他系统与此方法相同。基于PID算法的智能车辆控制。
2.PID调试的一般原理。当输出不振荡时,比例增益P增大。输出不振荡时,积分时间常数Ti减小。当输出不振荡时,微分时间常数Td增大。基于PID算法的智能车辆控制。
3.一般步骤。A.确定比例增益P。在确定比例增益P时,首先去掉PID的积分和微分项。一般采用Ti=0和td=0(参见PID的参数整定说明)进行PID纯比例调节。将输入设定为系统最大允许值的60%~70%,使比例增益P从0逐渐增大到系统输出。另一方面,比例增益P逐渐减小,直到系统振荡消失。记录此时的比例增益P,并将PID的比例增益P设置为当前值的60%~70%。调试了比例增益P。
4.确定积分时间常数Ti。在确定比例增益P后,设定较大积分时间常数Ti的初始值,然后逐渐减小Ti,直到系统振荡,然后Ti逐渐增加,直到系统振荡消失。记录此时的Ti,并将PID的积分时间常数Ti设置为当前值。150%~180%。调试了积分时间常数Ti。
5.确定积分时间常数td。积分时间常数td通常设置为零。要设置它,采取30%无振荡,同样的方法,磷和钛。对系统进行空载和有载共调,然后对PID参数进行微调,直至满足要求。
惯性克制算法:
int PID_Control(signed char Position) {
int Temp_P,Temp_D,Temp_PID,Temp_I,k; //声明三个变量,用于存放P、I、D三分量的运算结果(I没用上)
if(Position==-128) return (No_black); //错误处理(值得改进的地方) else {
Temp_I=Position;
for(k=0;k<5;k++)Temp_I+=Last_Position[k]; Temp_I*=I_coefficient;
Temp_P=P_coefficient*Position; //计算比例分量(P)=比例系数*本次位置差 Temp_D=D_coefficient*(Position-Last_Position[5]); //计算微分分量(D)=微分系数*(本次位置差-前3次的位置差)
//注意由于采样比较快,用本次位置-前3次位置才有足够大的控制量
Last_Position[6]=Last_Position[5]; Last_Position[4]=Last_Position[3]; Last_Position[3]=Last_Position[2]; Last_Position[2]=Last_Position[1]; Last_Position[1]=Last_Position[0];
Last_Position[0]=Position; /*保存前5次的位置,以备用。
Temp_PID=Temp_P+Temp_D+Temp_I; //P分量和D分量相加,得到控制量。 if(Temp_PID>5000) Temp_PID=5000; //防止控制量溢出
if(Temp_PID<-5000) Temp_PID=-5000; //控制量-5000~5000作为左右满舵 Temp_PID=Temp_PID*1/5; //-1000~+1000是左右满舵的输出,因此需要除以0.5
/*单片机浮点运算非常慢,所以用乘2除5两次定点运算来替代定点数要先乘后除,才能保证精度,同时要防止溢出,用起来比较麻烦,但CPU和内存开销小。*/
return (Temp_PID);
寻光,避障算法
没有障碍物就进入寻光模式 case Barrier_Status : Avoid_Obstacle(); break; //检测到障碍进入避障状态 default: break; } }
矢量合成,X,Y两个轴, x=0; y=0;
//1号光敏电阻,无Y轴,X为负 x=x-Intensity*Light[0];
//2号光敏电阻,X为-0.707,Y为0.707,45度 x=x-(Intensity *Light[1]*707)/1000; y=y+(Intensity *Light[1]*707)/1000; //3号光敏电阻,X为0,Y为正 y=y+Intensity * Light[2];
//4号光敏电阻,X,Y都为+0.707,45度 x=x+(Intensity*Light[3]*707)/1000; y=y+(Intensity*Light[3]*707)/1000; //5号光敏电阻,Y为0,X为正 x=x+Intensity*Light[4]; y=y;
采用了TA0来发生红外线,不干扰CPU的运行:
设置数组,对应频率分别为38,41,44,48,54,60,67
TACTL = TASSEL_2 + TACLR + MC_1 ; //TIMER_A时钟源选为SMCLK,清TAR TACCR0 = 44; //产生约38KHZ的PWM输出,SMCLK=4M,105个时钟周期
TACCTL0 = OUTMOD_4; //翻转模式产生占空比为50%的PWM }
避障底层程序:
void Measure_Distance() {
unsigned char flag_1=0,flag_2=0,flag_3=0,flag_4=0,flag_0=0;
unsigned char i,Frequency[5] = {29,36,44,47,51}; //66,54,44,42,38 for (i=0;i<5;i++)
{ TACCR0 = Frequency[i]; // 1
if(flag_0==0) {
Delay(34); PIRE1_H; // 打开1号传感器 Delay(34); // 延迟,等待数据稳定
if(IRE1_IN==0) // 如果接收到的信号为低电平,表明前方有障碍物 {flag_0 = 1;BarrierData[0]=5-i;} else BarrierData[0]=0; PIRE1_L; }
以上数据部分来源于网络,感谢大家的分享!