PID算法

typedef struct PID
{
    int  SetPoint;     //设定目标 Desired Value
    long SumError;                //误差累计
    double  Proportion;         //比例常数 Proportional Cons
    double  Integral;           //积分常数 Integral Const
    double  Derivative;         //微分常数 Derivative Const
    int LastError;               //Error[-1]
    int PrevError;               //Error[-2]
} PID;

/*******************************************************************************
* 函数名称 : IncPIDCalc
* 函数描述 : 增量式 PID 控制计算
* 函数输入 : int 当前位置
* 函数输出 : 无
* 函数返回 : 增量式PID结果
*******************************************************************************/
int IncPIDCalc(int NextPoint)
{
    int iError, iIncpid;
    //当前误差
    iError = sptr->SetPoint - NextPoint;
    //增量计算
    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);
}
/*******************************************************************************
* 函数名称 : LocPIDCalc
* 函数描述 : 位置式 PID 控制计算
* 函数输入 : int 当前位置
* 函数输出 : 无
* 函数返回 : 位置式PID结果
*******************************************************************************/
int LocPIDCalc(int NextPoint)
{
    int  iError,dError;
    iError = sptr->SetPoint - NextPoint;       //偏差
    sptr->SumError += iError;       //积分
    dError = iError - sptr->LastError;     //微分
    sptr->LastError = iError;
    return(sptr->Proportion * iError            //比例项
           + sptr->Integral * sptr->SumError   //积分项
           + sptr->Derivative * dError);        //微分项
}

chatGPT 3.5写的PID控制电机速度算法代码(感觉思路挺清晰的)​​​​​​​

PID控制在电机速度控制中被广泛使用,下面我们来讲解一下其具体代码实现,同时解析PID控制中的积分、比例和微分过程。

//定义控制参数
double Kp = 1.0;
double Ki = 0.5;
double Kd = 0.1;

//定义误差变量
double error = 0;
double last_error = 0;
double sum_error = 0;

//定义目标速度和当前速度
double desired_speed = 100;
double current_speed = 0;

//定义时间变量
unsigned long current_time = 0;
unsigned long last_time = 0;

//定义输出变量
double output = 0;

//定义PID控制函数
double pid_controller() 
{
    current_time = millis();    //获取当前时间
    double dt = (current_time - last_time) / 1000.0;    //计算时间变化量

    //计算误差
    error = desired_speed - current_speed;
    sum_error += error * dt;
    double d_error = (error - last_error) / dt;

    //计算控制量
    output = Kp * error + Ki * sum_error + Kd * d_error;

    //更新变量值
    last_error = error;
    last_time = current_time;

    return output;
}

//电机速度控制函数
void motor_control() 
{
    double target_speed = pid_controller();    //获取目标速度
    //使用PWM输出控制电机运行速度
    analogWrite(motor_pin, target_speed);
}

//主函数
void loop() 
{
    //获取电机当前速度数据
    current_speed = analogRead(motor_speed_pin);
    motor_control();    //执行电机速度控制函数
}

以下是PID控制温度的示例代码,其中包含了比例、积分和微分三个过程的实现:

#define SETPOINT 50.0   // 设定温度
#define KP 2.0          // 比例系数
#define KI 0.5          // 积分系数
#define KD 0.1          // 微分系数

double currentTemp = 0.0;   // 当前温度
double error = 0.0;         // 温度偏差
double lastError = 0.0;     // 上次温度偏差
double integral = 0.0;      // 积分项
double derivative = 0.0;    // 微分项 

// PID控制函数
void pid_control() {
  error = SETPOINT - currentTemp;  // 当前温度偏差
  integral += error;              // 加上当前的偏差
  derivative = error - lastError;  // 当前偏差与上次偏差的差
  lastError = error;              // 更新上次偏差
  
  // 计算控制量
  double controlValue = KP * error + KI * integral + KD * derivative;

  // 更新控制量
  // TODO: 将控制量更新到输出端口,控制温度
}

其中,各个符号的含义如下:

  • SETPOINT:设定温度
  • KP:比例系数,用于根据温度偏差来计算比例调节量
  • KI:积分系数,用于根据温度偏差来计算积分调节量
  • KD:微分系数,用于根据温度偏差来计算微分调节量
  • currentTemp:当前温度
  • error:当前温度偏差,即设定温度与当前温度的差
  • lastError:上一次的温度偏差,用于计算微分项
  • integral:积分项,用于记录历史温度偏差的积累量
  • derivative:微分项,用于记录温度偏差变化率

PID控制的核心在于通过比例、积分、微分三项调节量来控制输出端口,从而使得控制量逐渐趋近于设定值。在代码中,比例项根据当前温度偏差计算得出,积分项用于记录历史温度偏差的积累量,微分项用于记录温度偏差的变化率,三项调节量相加即得到最终的控制量,将控制量输出至输出端口即可完成PID控制。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值