电控---PID算法

控制的基本知识

控制是指对一个系统或过程施加作用,使其按照预定的目标或规律运行的过程。

控制系统的基本组成

  • 控制器:是控制系统的核心部分,它根据系统的输入和输出信息,按照一定的控制策略产生控制信号,以调节被控对象的行为。如工业自动化中的PLC(可编程逻辑控制器)、DCS(分布式控制系统)等。
  • 执行器:接受控制器发出的控制信号,并将其转换为相应的物理动作,对被控对象施加控制作用,常见的有电机、阀门、液压缸等。
  • 被控对象:是控制系统所要控制的设备、过程或系统,如加热炉、水箱、生产流水线等。
  • 传感器:用于检测被控对象的状态或输出信息,将物理量转换为电信号等便于处理的信号形式,反馈给控制器,如温度传感器、压力传感器、流量传感器等。

控制方式

  • 开环控制
    • 原理:控制器根据给定的输入信号,按照一定的控制规律产生控制信号,直接作用于被控对象,而不考虑被控对象的实际输出情况。
    • 特点:结构简单、成本低,但控制精度相对较低,抗干扰能力较弱,适用于对控制精度要求不高、干扰较小的场合,如普通的定时器控制的路灯开关系统。
  • 闭环控制
    • 原理:将被控对象的输出信号反馈到输入端,与给定输入信号进行比较,得到偏差信号,控制器根据偏差信号进行调节,使偏差趋于零,从而实现对被控对象的精确控制。
    • 特点:控制精度高、抗干扰能力强,但结构复杂、成本较高,常用于对控制精度和稳定性要求较高的场合,如工业生产中的温度、压力、流量等控制系统。

PID是闭环控制

在这里插入图片描述
在这里插入图片描述

控制性能指标

  • 稳定性:是控制系统的首要性能指标,指系统在受到干扰后,能够恢复到原来的平衡状态或跟踪给定输入的能力。一个稳定的控制系统才能正常工作,不稳定的系统无法实现有效的控制。
  • 快速性:反映了系统对输入信号的响应速度,通常用上升时间、调节时间等指标来衡量。快速性好的系统能够快速跟踪输入信号的变化,提高系统的工作效率。
  • 准确性:指系统的输出与给定输入之间的接近程度,常用稳态误差来衡量。准确性越高,系统的控制精度越高,能够更好地满足实际应用的要求。

控制理论基础

  • 经典控制理论:主要以传递函数为数学模型,采用频率响应法、根轨迹法等分析和设计控制系统,适用于单输入单输出、线性定常系统的控制,在20世纪40-50年代得到了广泛的发展和应用,如PID控制就是经典控制理论的典型应用。
  • 现代控制理论:以状态空间法为基础,能处理多输入多输出、非线性、时变系统等复杂系统的控制问题,包括最优控制、自适应控制、鲁棒控制等先进控制方法,在航空航天、机器人控制等领域有着重要应用。

常见的控制算法

除了PID控制算法外,还有以下常见算法:

  • 模糊控制:以模糊集合论、模糊语言变量及模糊逻辑推理为基础的一种智能控制方法,不需要建立精确的数学模型,适用于复杂、难以精确建模的系统,如洗衣机的模糊控制,根据衣物的重量、脏污程度等模糊信息自动调整洗涤时间和力度。
  • 神经网络控制:利用人工神经网络的自学习、自适应和非线性映射能力,对复杂系统进行建模和控制,具有很强的容错性和鲁棒性,在机器人控制、图像处理等领域有广泛应用。
  • 预测控制:通过预测模型预测系统未来的输出,根据预测结果和给定的性能指标,在线滚动优化控制策略,适用于大滞后、多变量、强耦合的复杂工业过程控制。

PID算法

PID控制器中的P(比例)、I(积分)、D(微分)是三种基本的控制作用,它们在控制系统中各自发挥着独特的作用,以下是对它们的详细解释:

P(比例)

  • 定义:比例控制是一种最简单的控制方式,其控制作用与偏差成正比关系。即控制器的输出信号u(t)与输入偏差e(t)之间的关系为u(t) = Kp * e(t),其中Kp为比例系数。
    在这里插入图片描述
  • 作用
    • 快速响应偏差:能够快速对偏差做出反应,偏差一旦出现,比例控制立即产生相应的控制作用,试图减小偏差。
      比如在水箱水位控制中,如果水位低于设定值,比例控制器会根据偏差大小成比例地打开进水阀门,偏差越大,阀门开度越大,进水速度越快。
    • 确定系统响应速度:比例系数Kp决定了系统的响应速度。Kp越大,系统对偏差的反应越灵敏,控制作用越强,系统输出能更快地向设定值靠近。
  • 理解:可以将比例控制想象成一个“即时反应”机制,它只关注当前的偏差情况,偏差大就加大控制力度,偏差小就减小控制力度,就像一个人根据当前看到的情况立即做出反应一样。但它的局限性在于,仅靠比例控制往往无法使系统完全达到设定值,可能会存在一定的稳态误差,因为它只考虑了当前偏差,没有考虑偏差的历史积累和变化趋势。

I(积分)

  • 定义:积分控制作用是对偏差随时间的积累进行运算,其输出与偏差的积分成正比,其中Ki为积分系数。

  • 在这里插入图片描述

  • 作用

    • 消除稳态误差:只要系统存在偏差,积分作用就会不断累积,随着时间的增加,积分项会逐渐增大,直到偏差为零,使系统达到无差调节。
      例如在温度控制系统中,若比例控制使温度接近设定值但仍有小偏差,积分作用会逐渐增加加热功率,最终消除这个偏差。
    • 提高控制精度:积分作用能够对系统的微小偏差进行持续调节,使系统的输出更加精确地跟踪设定值,提高系统的控制质量。
  • 理解:积分控制就像是一个“记忆”机制,它会记住过去所有时刻的偏差情况,并将这些偏差积累起来,根据积累的结果来调整控制作用。它的目的是消除系统过去产生的偏差对当前的影响,让系统能够更加准确地达到设定值。不过,积分作用也不能过强,否则可能会导致系统超调量过大,甚至引起系统振荡。

D(微分)

  • 定义:微分控制作用与偏差的变化率成正比,其中Kd为微分系数。

  • 在这里插入图片描述

  • 作用

    • 预测偏差变化趋势:微分环节能够根据偏差的变化速度来提前预测偏差的变化趋势,在偏差还没有明显增大或减小之前,就提前给出相应的控制作用,起到“超前控制”的效果。
      比如在电机速度控制中,当发现速度变化过快时,微分控制会提前施加一个反向的控制作用,阻止速度继续快速变化。
    • 改善系统动态性能:通过提前调节,微分作用可以有效减小系统的超调量,缩短系统的调节时间,使系统更快地达到稳定状态,提高系统的稳定性和响应速度。
  • 理解:微分控制类似于一个“预测器”,它不仅仅关注当前的偏差,更关注偏差的变化趋势。就像一个人根据事物的发展趋势提前做出判断和准备一样,微分控制能够提前对可能出现的偏差变化做出反应,使系统的控制更加平稳、快速。但微分控制对噪声比较敏感,因为噪声可能会导致偏差的变化率出现虚假的波动,从而使微分控制产生误动作。

PID补充算法

在PID控制算法中,为了改善控制性能、避免系统出现异常情况,常使用积分限幅、积分分离、变速积分、积分先行、输出限幅等补充算法,下面为你详细讲解:

积分限幅

  • 原理
    在PID算法中,积分项会对误差进行不断累积。在一些情况下,误差可能会持续存在或者较大,导致积分项不断增大,进而使控制器输出大幅度变化,可能引起系统超调甚至不稳定。积分限幅就是对积分项的大小进行限制,当积分项超过设定的上限或下限时,将其限制在这个范围之内。
  • 实现方式
    在计算积分项时,添加判断逻辑。假设积分项为 I I I,积分限幅上限为 I m a x I_{max} Imax,下限为 I m i n I_{min} Imin,则积分项更新后需要进行如下判断:
# 计算积分项
I = I + Ki * e * dt
if I > I_max:
    I = I_max
elif I < I_min:
    I = I_min

积分分离

  • 原理
    在系统偏差较大时,积分作用可能会导致系统超调过大,因为此时误差较大,积分项会快速累积。积分分离算法的核心思想是当偏差绝对值 ∣ e ∣ |e| e 大于某个设定的阈值 β \beta β 时,取消积分作用(令积分项为 0即直接舍去);当偏差绝对值小于等于阈值时,再引入积分作用,这样可以有效减小系统的超调。
  • 实现方式
if abs(e) > beta:
    I = 0
else:
    I = I + Ki * e * dt

变速积分

  • 原理
    积分分离算法是简单地在偏差较大时取消积分作用,而变速积分则是根据偏差的大小动态调整积分速度。当偏差较大时,积分速度慢,减小积分项的累积;当偏差较小时,积分速度快,加快消除稳态误差。可以通过一个比例系数 f ( e ) f(e) f(e) 来实现积分速度的调整, f ( e ) f(e) f(e) 是关于偏差 e e e 的函数,偏差越大, f ( e ) f(e) f(e) 越小。
  • 实现方式
    假设 f ( e ) f(e) f(e) 是一个根据偏差大小计算的系数,范围在 [ 0 , 1 ] [0, 1] [0,1] 之间,则积分项更新公式为:
f_e = calculate_f_e(e)  # 根据偏差计算系数 f(e)
I = I + Ki * f_e * e * dt

积分先行

  • 原理
    传统的PID控制中,是先计算比例、积分、微分三项的和得到控制量。而积分先行是先对积分项进行单独处理和输出,比例和微分部分根据积分项的输出结果以及当前误差进行计算。这样可以在系统启动或设定值突变时,避免积分项的快速累积导致的超调问题,让积分作用更加平滑地加入到控制过程中。
  • 实现方式
# 先更新积分项
I = I + Ki * e * dt
# 积分项单独输出
u_I = I
# 计算比例和微分项
u_P = Kp * e
u_D = Kd * (e - e_prev) / dt
# 最终控制量
u = u_I + u_P + u_D

输出限幅

  • 原理
    控制器的输出通常需要有一定的范围限制,例如执行器(如电机、阀门等)有其允许的最大和最小工作范围。如果PID控制器的输出超出这个范围,可能会损坏执行器或者导致系统异常。输出限幅就是对控制器的最终输出进行限制,使其在设定的范围之内。
  • 实现方式
    假设控制器输出为 u u u,输出限幅上限为 u m a x u_{max} umax,下限为 u m i n u_{min} umin,则:
if u > u_max:
    u = u_max
elif u < u_min:
    u = u_min

PID代码实现示例

利用cubemx和keil开发
在main.c文件中添加以下 PID 控制函数

#include "main.h"
#include "tim.h"
#include "gpio.h"

// PID结构体定义
typedef struct {
    float Kp;  // 比例系数
    float Ki;  // 积分系数
    float Kd;  // 微分系数
    float setpoint;  // 设定值
    float integral;  // 积分项
    float prev_error;  // 上一次的误差
} PID_HandleTypeDef;

// PID初始化函数
void PID_Init(PID_HandleTypeDef *pid, float Kp, float Ki, float Kd, float setpoint) {
    pid->Kp = Kp;
    pid->Ki = Ki;
    pid->Kd = Kd;
    pid->setpoint = setpoint;
    pid->integral = 0.0;
    pid->prev_error = 0.0;
}

// PID计算函数
float PID_Compute(PID_HandleTypeDef *pid, float current_value) {
    float error = pid->setpoint - current_value;
    pid->integral += error;
    float derivative = error - pid->prev_error;
    float output = pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative;
    pid->prev_error = error;
    return output;
}

// 电机控制函数
void Motor_Control(float pwm_value) {
    if (pwm_value > 0) {
        // 正转
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (uint32_t)pwm_value);
    } else if (pwm_value < 0) {
        // 反转
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (uint32_t)(-pwm_value));
    } else {
        // 停止
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
    }
}

在main函数中使用 PID 控制电机

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_TIM3_Init();

    // 启动PWM输出
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

    // PID参数初始化
    PID_HandleTypeDef pid;
    PID_Init(&pid, 1.0, 0.1, 0.01, 500.0);  // 设定值为500

    // 模拟当前电机速度
    float current_speed = 0.0;

    while (1)
    {
        // 计算PID输出
        float pwm_value = PID_Compute(&pid, current_speed);

        // 限制PWM值在0-1000范围内
        if (pwm_value > 1000) {
            pwm_value = 1000;
        } else if (pwm_value < -1000) {
            pwm_value = -1000;
        }

        // 控制电机
        Motor_Control(pwm_value);

        // 模拟电机速度变化
        current_speed += pwm_value * 0.01;

        HAL_Delay(10);
    }
}

以凡人之躯,比肩神明。 —塞涅卡

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值