PID知识点

在这里插入代码片
```struct Pid_struct_def {
	uint32_t    iPidSamples;
	uint32_t    ulSampleCount;
	float	fCurrentCo;         //!< pid output (pwm) Pid输出(pwm)
	float	lastError;          //!< used for D term 用于D项
	float	cumulError;         //!< cumulative error 累积误差
	float	pedestal;           //!< opening setting for the valve 阀门开度设定
	float	fTemporaryCo;       // holds the Co for a step down setpoint 保持Co为降阶设定值
    float   lastKi;             //!< Ki coeff used last cycle, needed to update  cumul_error if changing Ki coeff使用上一个周期,如果更改,需要更新cumul_error
    float   lastCurrent;        //!< measured valve current 测量阀电流
	bool	bHighPIDs;

};
void updateP1Pid(struct Pid_struct_def *my_pid, float setpoint, float cv, bool *stepDown, uint16_t *StepUp){

...............
 pedestal = DispenseConfig.V1Pedestal/65535.0F;//DispenseConfig.V1Pedestal = 11666  pedestal = 0.17

    保存上一次偏差 
     //error = safeDiv((setpoint - cv), sensorSerial.FullScale[1], (setpoint - cv)/50.0F);  
     // safe full scale conversion, use 50 for safe full scale
    saveError = error = safeDiv((setpoint - cv), 50.0F, (setpoint - cv)/50.0F);   // safe full scale conversion, use 50 for safe full scale 
        if (error > error_max)  
        error = error_max;
    if (error < -error_max)
        error = -error_max;
        if (fabs(averageError) > (pidTuningParams.HiBandUpCloseErrThreshold / 10))		// 高波段上误差阈值  was 2
	{
		error += 1.0F;
	}
	//fabs,求双精度浮点数的绝对值
	if (( (setpoint - Sensors.fP2PidPsia) < UltraLowPidCoefs.fPsiaThreshold) ) { // && (!my_pid->bHighPIDs || !Status.FLAGS.ByBits.bVerifying)) {
		if ( fabs(error) < pidTuningParams.UltraLoBandUpCloseErrThreshold) {	// was 0.0025F
			Kp = UltraLowPidCoefs.UpClose.fKp;
			Ki = UltraLowPidCoefs.UpClose.fKi;
			Kd = UltraLowPidCoefs.UpClose.fKd;
		}
		else {
			Kp = UltraLowPidCoefs.Up.fKp;
			Ki = UltraLowPidCoefs.Up.fKi;
			Kd = UltraLowPidCoefs.Up.fKd;
		}
	}
	else if (( (setpoint - Sensors.fP2PidPsia) < LowPidCoefs.fPsiaThreshold) ) { // && (!my_pid->bHighPIDs || !Status.FLAGS.ByBits.bVerifying)) {
        if ( fabs(error) < pidTuningParams.LoBandUpCloseErrThreshold) {			// was 0.0025F
            Kp = LowPidCoefs.UpClose.fKp;
            Ki = LowPidCoefs.UpClose.fKi;
            Kd = LowPidCoefs.UpClose.fKd;
        }
        else {
            Kp = LowPidCoefs.Up.fKp;
            Ki = LowPidCoefs.Up.fKi;
            Kd = LowPidCoefs.Up.fKd;
        }
    }
    else {
        // use the high PID coefficients 
        if ( fabs(error) < pidTuningParams.HiBandUpCloseErrThreshold) {			// was 0.01F
            Kp = HighPidCoefs.UpClose.fKp;
            Ki = HighPidCoefs.UpClose.fKi;
            Kd = HighPidCoefs.UpClose.fKd;
        }
        else {
            Kp = HighPidCoefs.Up.fKp;
            Ki = HighPidCoefs.Up.fKi;
            Kd = HighPidCoefs.Up.fKd;
        }
    }
    
	error = saveError; 将上一次偏差 
	//使调优独立于出口sigproc
    Ki = Ki  * sigprocParam.sigprocTimerTic[1];   // Make tuning independant of outlet sigproc
    Kd = Kd  * sigprocParam.sigprocTimerTic[1];   // Make tuning independant of outlet sigproc
    if((setpoint > LowPidCoefs.fPsiaThreshold) && (Status.FLAGS.ByBits.uState == DS_VERIFY_COLLECT))//验证收发
	{		
		Kp = VerifyPIDMultiplier.fKp * Kp;
		Ki = VerifyPIDMultiplier.fKi * Ki;
		Kd = VerifyPIDMultiplier.fKd * Kd;
				
	}
	  Pterm = Kp * error;
    
    // check for Nan //检查Nan
    if (my_pid->cumulError != my_pid->cumulError) //累积误差
        my_pid->cumulError = 0.0F;
        
    // iTerm always needs a windup limit // term总是需要一个windup limit
    if (0 != Ki) {
        cumul_limit_pos = (1.0F - pedestal)/Ki;//pedestal = 0.17   超低10  低18 高66.6
        cumul_limit_neg = ( - pedestal)/Ki;
    }        
    else {
        cumul_limit_pos = 100;      // doesn't really matter 这并不重要
        cumul_limit_neg = 100;      // doesn't really matter
    }
    //累积误差
    if (my_pid->cumulError > cumul_limit_pos)
        my_pid->cumulError = cumul_limit_pos;
    if (my_pid->cumulError < cumul_limit_neg)
        my_pid->cumulError = cumul_limit_neg;
    //加载之前的累积误差
    iTerm = Ki * ( my_pid->cumulError + error);  // 更新i系数    // load the previous cumulative error
    
    dTerm = Kd * (error - my_pid->lastError); 更新D系数// // 计算误差变化率
    
    my_pid->fCurrentCo = pedestal + Pterm + iTerm + dTerm;
 if (my_pid->fCurrentCo > 1.0F)
        my_pid->fCurrentCo = 1.0F;
    if (my_pid->fCurrentCo < 0.0F)
        my_pid->fCurrentCo = 0.0F;
        
    my_pid->cumulError += error;     // save for next round //保存到下一轮
    my_pid->lastError=error;         // 更新上一次误差
    my_pid->lastKi = Ki;      




从而实现PID自动定位
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值