学习制作平衡小车:(四)PID学习、位置PID参数整定以及匿名上位机显示

一、PID学习

    PID的知识网上有很多教学讲解的非常清楚,可以再参考学习【平衡小车之家】的视频教程。

二、位置PID学习

位置PID控制公式为:Pwm=Kp*e(K)+Ki*∑e(K)+Kd[e(K)-e(k-1)];其中:

Kp=设定的比例系数;Ki=设定的积分系数;Kd=设定的微分系数;e(K)=当前差(值);e(K-1)=上次差(值);∑e(K):历次差(值)的累积;

C语言实现函数:

int Position_PID(int encoder,int target)
{
	float position_Kp=10,position_Ki=0.03,position_Kd=15;
	static float bias,pwm,integral_bias,last_bias;
	bias=encoder-target; //计算偏差
	integral_bias+=bias; //求出偏差的积分
	pwm=position_Kp*bias+position_Ki*integral_bias+position_Kd*(bias-last_bias);	
	last_bias=bias;	     //存储当前偏差作为下次计算的依据
	return pwm;
}

函数实现流程:首先必须设定一个标准的定时,循环读取和反馈PID控制;

                          读取电机Encoder编码;

                          PID控制计算,计算出控制量;

                          PID控制量作为电机PWM控制电机转动;

encoder_R=__HAL_TIM_GET_COUNTER(&htim3);    //读取右电机编码器的值		
motor_R_PWM=Position_PID(encoder_R,target); //PID控制计算
Set_PWM(motor_R_PWM,0);			    //取绝对值/限幅/赋值给电机
data_to_computer(&encoder_R,&target);	    //上位机发送数据

三、匿名科创地面站(上位机)使用(简单的数据波形使用):

1、首先查看自己的USB转TTL设备使用的端口-不知道怎么查看的可以直接打开串口调试助手查看;

2、打开匿名客串地面站V4.34,在“程序设定”里设定刚才查到的端口号和设定的波特率;

3、点击右下角打开连接,如果程序运行正常,会看到RX有数据的传输;

4、点击“高级收码”,“帧格式设置”,选择“1”,勾选“使能该帧”和“显示该帧”;下面的“数据容器设置”中,选择页标签1的数据来源=帧1,数据位置=1,选择页标签“2”的数据来源=帧1,数据位置=4;

5、点击进入“数据波形”页面,勾选UserData_1和UserData_2,点击“开始显示”,即可在“数据波形”页面看到发送来的读取的点击Encoder编码数据和设定的目标值数据:

四、位置PID参数整定:

    在使用PID控制中,比例控制是最基本的控制,根据需要PID控制可以衍生出P或PI、PD控制。其中:

    比例P参数主要用于提高响应速度-即影响快速性;

    积分I参数主要用于减少静差-即影响准确性;

    微分D参数主要用于抑制震荡-即影响稳定性;

我用的电机的编码器是260线,A/B双相再经X4设置后,电机输出轴转动1轴的总编码数=1040,这里设定位置PID的目标=1040:

int target=1040;	//位置PID参数整定:目标值

在PID控制子函数中设置Kp/Ki/Kd的值,并通过观察波形对PID参数进行调整:

1、设定position_Kp=500,position_Ki=0,position_Kd=0,波形如下:

Kp取值过高,电机处于抖动状态;

2、设定position_Kp=30,position_Ki=0,position_Kd=0,波形如下:

可以看出,只要比例P参数设定得当,单独的比例P控制就基本上能够达到预定目的,但是存在过量,需要减少Kd;存在震荡,可以加入Kd系数(一般Kd>Kp)抑制震荡;并且存在静差(稳定值同目标值有差异),可以加入Ki减少静差(Ki一般设置Kp的1/200左右);

3、设定position_Kp=10,position_Ki=0,position_Kd=15,波形如下:

五、增量式速度PID

1、增量PID控制公式:

pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]

在闭环速度控制中,可以只使用PI控制就能够达到目的,所以公式可以简化为:

pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)

2、C语言实现的函数

int Incremental_PI (int Encoder,int Target)
{ 	
   float Kp=20,Ki=30;	
   static int Bias,Pwm,Last_bias;
   Bias=Encoder-Target;                //计算偏差
   Pwm+=Kp*(Bias-Last_bias)+Ki*Bias;   //增量式PI控制器
   Last_bias=Bias;	               //保存上一次偏差 
   return Pwm;                         //增量输出
}

3、测试函数

先测试在最大pwm时电机编码器5ms读取数据的差额:

设定pwm=7000,并使电机向前转动:

__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_3,7000);//右电机Pwm输出
Motor_R_Forward();	                         //测试:使右电机向前转动

5ms定时循环读取并使用printf串口打印:

/*由stm32f1xx_it.c中void SysTick_Handler(void)子函数产生的5ms定时*/
if(delay5ms_flag==1)			//5ms定时
{		
    encoder_R=__HAL_TIM_GET_COUNTER(&htim3);     //测试:读取右电机编码器的值
    printf("encoder_R=%d\r\n",encoder_R);        
    delay5ms_flag=0;	
}

pwm=7000时每5ms编码器大约=70

设定目标值

int target=30;	//速度PID参数整定目标值:不能超过Pwm=7000时的速度

测试函数

/*    电机速度PID闭环控制测试代码    */
encoder_R=__HAL_TIM_GET_COUNTER(&htim3);     	//测试:读取右电机编码器的值
bias_encoder_R=encoder_R-last_encoder_R;	//计算同上次的差值:M法则 5ms编码器数据
motor_R_PWM=Incremental_PI(bias_encoder_R,target);//PI控制			Set_PWM(motor_R_PWM,0);	//取绝对值/限幅/电机赋值			last_encoder_R=encoder_R;//保存本次编码器值
data_to_computer(&bias_encoder_R,&target);	//上位机发送数据

下载的原代码加压后需要打开目录下的"Car_Test_PID"stm32CubeMX工程,重新生产MDK工程,编译前,点魔法棒“Options for Target”,在C/C++下添加自己的库函数“My  Modular”文件夹的目录,并在“Application/user”组下添加目录下的所有.c文件,再编译。

  • 33
    点赞
  • 229
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值