提示:本文章的PID位置控制是在前一个的PID速度控制,的基础上实现的,这一章节中不需要额外的cubemx的配置,只需要写简单的代码即可。
前言
提示:这里可以添加本文要记录的大概内容:
前一节讲解了PID的速度控制,这节讲如何进行位置控制。
提示:以下是本篇文章正文内容,下面案例可供参考
一、代码
本文是使用PI增量式控制 – 控制电机的转速。
对于增量式pid和位置式pid的区别可以查看这篇文章
1.pid
在原有的代码上(pid.c)添加以下代码:
/*
* 函数功能:位置式PID控制器
* 入口参数:编码器测量位置信息,目标位置
* 返回 值:电机PWM
* 根据位置式离散PID公式
* pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
* e(k)代表本次偏差
* e(k-1)代表上一次的偏差
* ∑e(k)代表e(k)以及之前的偏差的累积和;其中k为1,2,,k;
* pwm代表输出
**************************************************************************/
int Position_PID (int position,int target)
{
float Kp=30,Ki=0.1,Kd=10;
static float Bias,Pwm,Integral_bias,Last_Bias;
Bias=target-position; //计算偏差
Integral_bias+=Bias; //求出偏差的积分
if(Integral_bias>4000)Integral_bias=4000; //对积分 限幅
if(Integral_bias<-4000)Integral_bias=-4000; //积分限幅 防止到达目标位置后过冲
Pwm=Kp*Bias+Ki*Integral_bias+Kd*(Bias-Last_Bias); //位置式PID控制器
Last_Bias=Bias; //保存上一次偏差
return Pwm; //增量输出
}
pid.h
int Position_PID (int position,int target);
2. encode文件
由于速度环的时候只有编码器当前的速度,所以需要将编码器的值累计即可。
encode.c
long int CurrentPosition;
/**************************************************************************
函数功能:读取编码器总计数
入口参数:定时器
返回 值:位置
**************************************************************************/
long int Read_CurrentPosition(void)
{
return CurrentPosition;
}
encode.h
#ifndef __ENCODE_H
#define __ENCODE_H
#include "main.h"
#define ENCODE_TIMX TIM4
int Read_Encoder(void);//读取计数器的值
long int Read_CurrentPosition(void);//读取编码器总计数
#endif
it.c文件
与速度控制的没多大变化,只是添加了CurrentPosition_
,
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//位置
{
if(htim==(&htim9))//因为我采用的是定时器6
{
int setcc=2508;
int moto_pwm;
int CurrentPosition_;
Read_Encoder();
CurrentPosition_=Read_CurrentPosition();
moto_pwm=Position_PID(CurrentPosition_,setcc);
moto_pwm=Xianfu_Pwm(moto_pwm);
Set_Pwm(moto_pwm);
printf("samples: %d ,%d ,%d\n",CurrentPosition_,setcc,moto_pwm);
}
}
二、PID配置
pid.c中的pid的三个参数需要自己调整
根据我的最终为30 0.1 10 最优