pid控制的倒立摆

4 minute read

做一个倒立摆

这个倒立摆,一开始是打算用自己做的结构,用木板和铝型材搭,用57步进电机驱动。这个结构有很大的问题,步进电机悬空,下盘不稳,很容易就整个结构一起震动,难以平衡。没上导线环,会绕线。只剩一张他的遗照了。

IMG_20190713_202732.png

图里还用了一个木制法兰盘23333用502做的(简直是魔鬼),连接到转轴上也是用502. 接下来直接去淘宝买了一套结构.

关键的代码也就是下面两个pid环。

两个pid环的代码

int PID_Angle_Cal(int ang_Now, int ang_Target)
{
    float dError,Bias=0;
    static float iError;
    Bias = ang_Now - ang_Target;
    iError += Bias;
    if (iError> 2200)	iError=2200;
    if (iError<-2200)	iError=-2200;//iError上下限
    dError = Bias - last_Bias;
    last_Bias = Bias;

    return ang_p * Bias + ang_i * iError + ang_d * dError;
}
int PID_Pos_Cal(int pos_Now, int pos_Target)
{
    float dError;
    static float Bias,last_Bias,iError;
  	Least = pos_Now - pos_Target;
    Bias *=0.8;
    Bias += Least * 0.2;//一阶低通滤波
	dError = Bias - last_Bias;
	last_Bias = Bias;
    iError += Bias;
    if (iError> 1900)	iError=1900;
    if (iError<-1900)	iError=-1900;
	return Bias * pos_p + iError * pos_i + dError * pos_d; 
} 

调试

一开始按网上的经验,只用pd控制,调了好久,一直效果不好,小幅抖动到大幅抖动,然后掉了。然后,突然意识到,会不会是Bias较小是时候,电机的扭力和控制量的关系与Bias较大时的关系相差较大。就想到,加上i的消除静差的作用应该就可以了。加上i之后,再调了一下就有下面的效果了。

补充一下调试过程

  1. 12位adc,读取电位器的值是0-4095,距离竖立位置的10%差值(左右5%)大概是400。我的电机控制量满速是16800。 我就大概取P位16800/(400/2)=84,可以看到倒立摆可以左右摇晃不倒1-2秒。
  2. 然后随缘调d,调到倒立摆比较快左右摇晃不倒更久一点时间,然后慢慢调小d,直到出现这个现象,在倒下前只往一个方向倾倒。
  3. 调i,i调起来比较麻烦,i的大小和控制频率有关。先说i的积分上限,我先把pid控制关闭,直接调电机速度控制量,找到电机将动未动的临界点(我大概是2200),把这时的控制量作为i的积分上限。观察发现仅在pd控制时(点2中说的现象),距离竖立位置的误差量大概是50-200,然后我取100来计算,用2200/100 = 22,我希望在10次计算(位置误差一直没有减小时)后达到积分上限,22/2=2.2。 在控制频率一定时(我的PID的控制频率是100Hz),i越大,系统的抖动越大,i越小,i的控制作用越不明显。
  4. 最后慢慢微调pid三个量得到更好的效果。