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控制。