多环串级PID

为什么要多环

单环只能单一控制速度或者位置,如果想要同时控制多个量如速度,位置,角度,就需要多个PID在这里插入图片描述

  • 速度环一般PI控制,位置环一般PD

程序

主函数

/*定义内环变量*/
float InnerTarget, InnerActual, InnerOut;
float InnerKp =, InnerKi =, InnerKd =;
float InnerError0, InnerError1, InnerErrorInt;

/*定义外环变量*/
float OuterTarget, OuterActual, OuterOut;
float OuterKp =, OuterKi =, OuterKd =;
float OuterError0, OuterError1, OuterErrorInt;

int main(void)
{
    Timer_Init();
    while (1)
    {
        /*用户在此处根据需求写入外环PID控制器的目标值*/
        OuterTarget = 用户指定的一个值;
    }
}

内环

void TIM2_IRQHandler(void)
{
    static uint64_t Count1, Count2;
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
    {
        Count1 ++;
        if (Count1 >= 内环调控时间)
        {
            Count1 = 0;

            /*内环每隔时间T1,程序执行到这里一次*/

            /*执行内环PID控制*/
            InnerActual = 读取内环实际值();

            InnerError1 = InnerError0;
            InnerError0 = InnerTarget - InnerActual;

            InnerErrorInt += InnerError0;

            InnerOut = InnerKp * InnerError0
                     + InnerKi * InnerErrorInt
                     + InnerKd * (InnerError0 - InnerError1);

            if (InnerOut > 上限) {InnerOut = 上限;}
            if (InnerOut < 下限) {InnerOut = 下限;}

            /*内环PID的输出值作用于执行器*/
            输出至被控对象(InnerOut);
        }
    }
}

外环

外环调控周期要大于等于内环,具体周期给多少,要不断尝试

Count2 ++;
if (Count2 >= 外环调控时间)
{
    Count2 = 0;

    /*外环每隔时间T2,程序执行到这里一次*/

    /*执行外环PID控制*/
    OuterActual = 读取外环实际值();

    OuterError1 = OuterError0;
    OuterError0 = OuterTarget - OuterActual;

    OuterErrorInt += OuterError0;

    OuterOut = OuterKp * OuterError0
             + OuterKi * OuterErrorInt
             + OuterKd * (OuterError0 - OuterError1);

    if (OuterOut > 上限) {OuterOut = 上限;}
    if (OuterOut < 下限) {OuterOut = 下限;}

    /*外环PID的输出值作用于内环PID的目标值*/
    InnerTarget = OuterOut;
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

双环PID调参

  • 参数越大,响应越快,但会出现抖动;参数越小,响应越慢,但更加平滑,需要自己取舍
  • 同时调节内环和外环是不可行的
  • 因为内环可以独立工作,我们要先调内环(要把外环给注释调),内环调好了,在内环的基础上调节外环

内环

Kp调法

  • 先让出现抖动,再减小使抖动消失

Ki调法

  • 与Kp类似
  • 先让出现抖动,再减小使抖动消失

外环

Kp

外环Kp不用怕超调,直接调到抖动再减小,用Kd减少超调

以一定速度到达指定位置

不能使innertarget=目标速度
正确做法是更改限幅,速度要小限幅就小

封装

typedef struct {
    float Target;
    float Actual;
    float Out;

    float Kp;
    float Ki;
    float Kd;

    float Error0;
    float Error1;
    float ErrorInt;
    
	float OutMax;
	float OutMin;
} PID_t;

初始化赋值方法

   PID_t Inner = {
      .Kp = 0.3,
      .Ki = 0.3,
      .Kd = 0,
      .OutMax = 100,
      .OutMin = -100
   };
```c
void PID_Update(PID_t *p)
{
    p->Error1 = p->Error0;
    p->Error0 = p->Target - p->Actual;

    if (p->Ki != 0)
    {
        p->ErrorInt += p->Error0;
    }
    else
    {
        p->ErrorInt = 0;
    }

    p->Out = p->Kp * p->Error0
           + p->Ki * p->ErrorInt
           + p->Kd * (p->Error0 - p->Error1);

    if (p->Out > p->OutMax) {p->Out = p->OutMax;}
    if (p->Out < p->OutMin) {p->Out = p->OutMin;}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值