无废话,上代码
#ifndef __PID_base_HPP
#define __PID_base_HPP
#ifdef __cplusplus
extern "C" {
#endif
class pid_base{//pid方法基类
protected:
float total_out;//总输出
float max_total_out;//PID最大输出限制
void Limit(float *value, float maxValue);//限幅
public:
pid_base();
virtual ~pid_base();
float Get_total_out(void);//获得最后一次的总输出
virtual void Set_kp(float kp);//设置kp
virtual void Set_ki(float ki);//设置ki
virtual void Set_kd(float kd);//设置kd
void Set_max_total_out(float max_total_out);//设置最大输出值
virtual float Calculate(float new_data) = 0;//计算并输出
};
#ifdef __cplusplus
}
#endif
#endif
#include "pid_base.hpp"
void pid_base::Limit(float *value, float maxValue){
if (*value>0 && *value>maxValue){
*value = maxValue;
} else if (*value<0 && *value<-maxValue) {
*value = -maxValue;
}
}
float pid_base::Get_total_out(){
return total_out;
}
void pid_base::Set_max_total_out(float max_total_out){
this->max_total_out = max_total_out;
}
#ifndef __PID_INC_HPP
#define __PID_INC_HPP
#ifdef __cplusplus
extern "C" {
#endif
#include "pid_base.hpp"
class pid_inc : public pid_base{//增量式pid的数据
private:
float kp; //比例系数
float kd; //微分系数
float p_out; //比例输出
float d_out; //微分输出
float lastError; //最后的误差值
float prevError; //上次的误差值
public:
pid_inc();
virtual ~pid_inc();
virtual void Set_kp(float kp);//设置kp
virtual void Set_kd(float kd);//设置kd
void Set_kp_kd(float kp, float kd);//设置kp、kd
virtual float Calculate(float new_data);//增量式PID计算函数,返回值是pid的输出
};
#ifdef __cplusplus
}
#endif
#endif
#include "pid_inc.hpp"
void pid_inc::Set_kp(float kp){
this->kp=kp;
}
void pid_inc::Set_kd(float kd){
this->kd=kd;
}
void pid_inc::Set_kp_kd(float kp, float kd){
Set_kp(kp);
Set_kd(kd);
}
float pid_inc::Calculate(float new_data){
lastError = new_data;
p_out = kp * lastError;
d_out = kd * (lastError - prevError);
total_out = p_out + d_out;
Limit(&total_out, max_total_out);
prevError = lastError;
return total_out;
}
#ifndef __PID_POS_HPP
#define __PID_POS_HPP
#ifdef __cplusplus
extern "C" {
#endif
#include "pid_inc.hpp"
class pid_pos : public pid_base{//标准位置式pid的数据
private:
float kp; //比例系数
float ki; //积分系数
float kd; //微分系数
float p_out; //比例输出
float d_out; //微分输出
float i_out; //积分输出
float lastError;//最后的误差值
float prevError;//上次的误差值
float target; //目标值
float present; //当前值
float max_i_out;//积分限幅
float i_Band; //积分分离
public:
pid_pos();
virtual ~pid_pos();
virtual void Set_kp(float kp);//设置kp
virtual void Set_ki(float ki);//设置ki
virtual void Set_kd(float kd);//设置kd
void Set_kp_ki_kd(float kp, float ki, float kd);//设置kpid
void Set_target(float target);//设置目标值
void Set_max_i_out(float max_i_out);//设置积分限幅值
void Set_i_Band(float i_Band);//设置积分分离值
void Clear_i_out(void);//清积分
virtual float Calculate(float new_data);//计算
};
#ifdef __cplusplus
}
#endif
#endif
#include "pid_pos.hpp"
void pid_pos::Set_kp(float kp){
this->kp = kp;
}
void pid_pos::Set_ki(float ki){
this->ki = ki;
}
void pid_pos::Set_kd(float kd){
this->kd = kd;
}
void pid_pos::Set_kp_ki_kd(float kp, float ki, float kd){
Set_kp(kp);
Set_ki(ki);
Set_kd(kd);
}
void pid_pos::Set_target(float target){
this->target = target;
}
void pid_pos::Set_max_i_out(float max_i_out){
this->max_i_out = max_i_out;
}
void pid_pos::Set_i_Band(float i_Band){
this->i_Band = i_Band;
}
void pid_pos::Clear_i_out(void){
i_out = 0;
}
float pid_pos::Calculate(float new_data){
present = new_data;
lastError =target - present;
p_out = kp * lastError;//比例输出
if(__fabs(lastError) < i_Band){
Limit(&i_out, max_i_out);
i_out += ki * lastError;
} else {
i_out = 0;
}
d_out = kd * (lastError - prevError);
total_out = p_out + i_out + d_out;
Limit(&total_out, max_total_out);
prevError = lastError;
return total_out;
}
感冒了未完待续