倒立摆入门详解+pid调参
倒立摆制作全过程
最近在练习pid的控制算法,就选用了2013年的电子设计国赛题目:倒立摆 。 首先给你们看看我的成果 注意哦:倒立摆不是靠上面黄色的传感器保持平衡的,而是通过下面的电机左右扭动使得摆杆不掉下来,难度可不小了。
材料准备
1.机械部分
如图所示选好电机和角位移传感器进行组装就好了,这个部分是我直接网上购买的,如果要自己装也是可以的,不过会比较麻烦,结构差不多的。
2.主控部分
3.代码编写以及调参
上面的话都是硬件部分,需要自己动手去制作的,接下来我教大家怎么给倒立摆调参。代码的话我已经把源码上传到我的资料那里了,里面都有详细解说的,大家可以直接去下载来看,可以理解的。
下面展示 main函数部分。
int main(void) { Stm32_Clock_Init(9); delay_init(72); JTAG_Set(JTAG_SWD_DISABLE); JTAG_Set(SWD_ENABLE); delay_ms(1000); delay_ms(1000); LED_Init(); EXTI_Init(); OLED_Init(); uart_init(72,128000); MiniBalance_PWM_Init(7199,0); Encoder_Init_TIM4(); Angle_Adc_Init(); //Baterry_Adc_Init(); Timer1_Init(49,7199); while(1) { //DataScope(); delay_flag=1; oled_show(); while(delay_flag); } }
学过32的基本都懂,就是需要用到的模块都初始化,然后启动定时器函数进入pid控制的中断进行偏差控制。
pid控制代码
int TIM1_UP_IRQHandler(void) { if(TIM1->SR&0X0001 { TIM1->SR&=~(1<<0); if(delay_flag==1) { if(++delay_50==10) delay_50=0,delay_flag=0; } Encoder=Read_Encoder(4); Angle_Balance=Get_Adc_Average(3,15); Balance_Pwm =balance(Angle_Balance); if(++Position_Target>4) Position_Pwm=Position(Encoder),Position_Target=0; Moto=Balance_Pwm-Position_Pwm; if(Angle_Balance<1600 || Angle_Balance>2660) Moto = 0; Xianfu_Pwm(); // if(Turn_Off(Voltage)==0) Set_Pwm(Moto); Led_Flash(100); // Voltage=Get_battery_volt(); Key(); } return 0; } int balance(float Angle) { float Bias; static float Last_Bias,D_Bias; int balance; Bias=Angle-ZHONGZHI; D_Bias=Bias-Last_Bias; balance=-Balance_KP*Bias-D_Bias*Balance_KD; Last_Bias=Bias; return balance; } int Position(int Encoder) { static float Position_PWM,Last_Position,Position_Bias,Position_Differential; static float Position_Least; Position_Least =Encoder-Position_Zero; Position_Bias *=0.8; Position_Bias += Position_Least*0.2; Position_Differential=Position_Bias-Last_Position; Last_Position=Position_Bias; Position_PWM=Position_Bias*Position_KP+Position_Differential*Position_KD; return Position_PWM; }
接下来就是重头戏了,调参部分 倒立摆要保持平衡,就需要有两个环,一个是角度环,保证摆杆能够不倒下来,再有一个是位置环,确保水平杆不会乱转。
角度环5ms采集一下 位置环25ms采集一次,电机控制是5ms控制一次。 这里位置环25ms是这样的出来的:首先尝试5ms,但是不论参数怎么调试都是反应剧烈,所以逐渐加大延长编码器采集时间,到了30ms的时候根据相同参数比较反应滞后,座椅最后确定25ms。