PID练习:增量PID(一),调节电机的速度

1、增量PID的原理、增量PID的最后公式
2、增量PID的代码;
3、stm32F4实现调节电机的速度。

1、增量PID
在这里插入图片描述
代码

//定义PID结构体
typedef struct 
{
   __IO int      SetPoint;                                 //设定目标 Desired Value
   __IO float    Proportion;                               //比例常数 Proportional Const
   __IO float    Integral;                                 //积分常数 Integral Const
   __IO float    Derivative;                               //微分常数 Derivative Const
   __IO int      LastError;                                //Error[-1]
   __IO int      PrevError;                                //Error[-2]
}PID;

/* 私有宏定义 ----------------------------------------------------------------*/
/*************************************/
// 定义PID相关宏
// 这三个参数设定对电机运行影响非常大
// PID参数跟采样时间息息相关
/*************************************/
#define  P_DATA      0.4                              // P参数
#define  I_DATA      0.3                              // I参数
#define  D_DATA      0.1                              // D参数

static PID sPID;
static PID *sptr = &sPID;
/* 扩展变量 ------------------------------------------------------------------*/
/* 私有函数原形 --------------------------------------------------------------*/
void IncPIDInit(void);
int32_t IncPIDCalc(int16_t NextPoint);


 if(KEY1_StateRead()==KEY_DOWN)  // 增速
    {
      /* 设置目标速度 */
      sptr->SetPoint +=50;    //50 pulse
    }
    if(KEY2_StateRead()==KEY_DOWN)  // 减速
    {
      /* 设置目标速度 */
      sptr->SetPoint -=50;
    }    

  if(start_flag) // 等待脉冲输出后才开始计时
  {
    time_count++;         // 每1ms自动增一
    if(time_count==200)
    {
      __IO int16_t count;
      __IO int para;
      
      /* 得到编码器计数值,200ms内的编码器数值,数值越大说明速度越大 */
      count = (int16_t)__HAL_TIM_GET_COUNTER(&htimx_Encoder);

      /* 计数得到增量式PID的增量数值 */
      para=IncPIDCalc(count);
      
      /* 根据增量数值调整当前电机速度 */
      PWM_Duty +=para;  
      
      if(PWM_Duty>999)PWM_Duty=1000;  
      if(PWM_Duty<0)PWM_Duty=0;

      /* 对速度值进行简单的处理, */
      cal += count*(1000/time_count); // 单位转换成秒//并累加
      i++;
      if(i==(1000/time_count))
      {
        i=0;
        cal /= (1000/time_count);     // 求平均,1s内采样5次
        // 11:编码器线数(转速一圈输出脉冲数),编码器4倍频
        // 34:电机减数比,内部电机转动圈数与电机输出轴转动圈数比,即减速齿轮比      
        printf("Speed %.2f r/s\n",cal/(11*4)/34);
        cal = 0;
      }
      __HAL_TIM_SET_COUNTER(&htimx_Encoder,0);
      L298N_DCMOTOR_Contrl(1,PWM_Duty); 
      time_count=0;      
    }
  }

/*********************PID参数初始化********************************/
void IncPIDInit(void) 
{
    sptr->LastError=0;            //Error[-1]
    sptr->PrevError=0;            //Error[-2]
    sptr->Proportion=P_DATA;      //比例常数 Proportional Const
    sptr->Integral=I_DATA;        //积分常数  Integral Const
    sptr->Derivative=D_DATA;      //微分常数 Derivative Const
    sptr->SetPoint=300;           //设定目标Desired Value
}
/********************增量式PID控制设计************************************/
/** 
  * 函数名称:增量式PID控制设计
  * 输入参数:当前控制量
  * 返 回 值:目标控制量
  * 说    明:无
  */
int32_t IncPIDCalc(int16_t NextPoint) 
{
  int iError,iIncpid = 0;                             //当前误差
  iError=sptr->SetPoint-NextPoint;                    //增量计算
  if( iError<3 && iError>-3 )                         //误差在正负3以内,则不做处理
    return iIncpid;
  iIncpid=(sptr->Proportion * iError)                 //E[k]项
              -(sptr->Integral * sptr->LastError)     //E[k-1]项
              +(sptr->Derivative * sptr->PrevError);  //E[k-2]项
  
  sptr->PrevError=sptr->LastError;                    //存储误差,用于下次计算
  sptr->LastError=iError;
  return(iIncpid);                                    //返回增量值
}
<think>好的,用户需要了解增量PID控制器的调试和参数调整方法。首先,我需要回顾增量PID的基本原理,确保自己理解正确。增量PID与位置式PID的区别在于输出的是控制量的增量,而不是绝对量,这有助于减少积分饱和的问题。 接下来,参数调整方法方面,常见的Ziegler-Nichols法、试凑法、优化算法等都需要涵盖。需要检查这些方法是否适用于增量PID,或者是否有特别的注意事项。比如,Ziegler-Nichols原本是针对位置式设计的,可能需要调整。 然后,调试步骤需要分阶段说明,比如初始参数设置、系统响应测试、参数细调等。需要强调逐步调整,避免系统不稳定。可能还要提到仿真工具的使用,如MATLAB/Simulink,帮助用户在实际应用前验证参数。 用户可能还关心常见问题,比如超调过大、响应慢或振荡,需要给出对应的解决策略。比如积分系数过大导致超调,可以减小积分时间或引入积分分离。这部分需要具体例子,帮助用户理解。 引用部分,虽然用户提供的引用是关于图像标题和人物搜索的,可能不直接相关,但系统要求添加引用标识,可能需要找到相关控制理论的文献,或者说明没有直接引用,但这里可能需要忽略或调整。 最后,生成的相关问题要覆盖参数作用、软件工具、优化算法、与位置式对比以及应用场景,确保用户能延伸学习。需要检查问题是否合理,是否覆盖用户可能感兴趣的方面。 确保使用正确的LaTeX格式,所有数学公式用$...$或$$...$$,比如PID公式中的$\Delta u(k)$。中文回答,结构清晰,分步骤和子标题,帮助用户逐步理解和应用。</think>### 增量PID控制器调试与参数调整方法 #### 1. 增量PID基础公式 增量PID的输出为控制增量$\Delta u(k)$,其表达式为: $$ \Delta u(k) = K_p \left[ e(k)-e(k-1) \right] + K_i e(k) + K_d \left[ e(k)-2e(k-1)+e(k-2) \right] $$ 其中$e(k)$为当前误差,$K_p$、$K_i$、$K_d$分别为比例、积分、微分系数[^1]。 #### 2. 参数调整方法 **2.1 Ziegler-Nichols法** 1. 先将$K_i=0, K_d=0$ 2. 逐渐增大$K_p$直至系统出现等幅振荡 3. 记录临界增益$K_u$和振荡周期$T_u$ 4. 按经验公式设定: - $K_p = 0.6K_u$ - $K_i = K_p/(0.5T_u)$ - $K_d = K_p \times 0.125T_u$ **2.2 试凑法步骤** 1. 先调$K_p$:增大至系统快速响应但无显著超调 2. 再调$K_i$:消除稳态误差,但避免积分饱和 3. 最后调$K_d$:抑制超调和振荡 **2.3 优化算法** - 使用遗传算法、粒子群优化等智能算法自动寻优 - 需要建立目标函数(如ITAE指标): $$ J = \int_{0}^{T} t|e(t)|dt $$ #### 3. 调试最佳实践 1. **仿真验证**:使用MATLAB/Simulink建立系统模型验证参数 2. **分段调试**: - 低速区:加强积分作用 - 高速区:增强微分控制 3. **抗饱和措施**: - 积分分离:当误差超过阈值时停止积分 - 微分先行:仅对测量值微分 #### 4. 常见问题与对策 | 现象 | 原因 | 解决方案 | |--------------|-------------------|--------------------------| | 持续振荡 | $K_p$过大或$K_d$不足 | 降低$K_p$,增大$K_d$ | | 响应迟缓 | $K_p$过小 | 逐步增大$K_p$ | | 稳态误差 | $K_i$不足 | 适当增大积分系数 | | 超调过大 | $K_d$不足 | 增大微分系数或加入滤波器 | #### 5. 参数整定工具推荐 1. MATLAB PID Tuner:提供自动整定与频域分析 2. LabVIEW PID控制工具包:支持实时调参 3. Python Control库:适用于算法仿真 ```python # Python增量PID示例代码 class IncrementalPID: def __init__(self, Kp, Ki, Kd): self.Kp, self.Ki, self.Kd = Kp, Ki, Kd self.e = [0, 0, 0] # 当前、前次、前两次误差 def update(self, error): delta_u = self.Kp*(error - self.e[0]) + self.Ki*error + self.Kd*(error - 2*self.e[0] + self.e[1]) self.e = [error, self.e[0], self.e[1]] return delta_u ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值