倒立摆入门详解+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。

经验分享 程序员 微信小程序 职场和发展