linuxCNC PID自整定

  • Post author:
  • Post category:linux


这是linuxCNC的PID自整定的代码,对于理解PID的整定过程有帮助。

参数的选择可参考:


临界比例度法整定PID参数


简述PID原理及临界比例度法参数整定_阿尘啊的博客-CSDN博客_临界比例度法整定pid参数

下面代码中,PID方法的Kp的选择是1/0.6 = 1.66。

/*
 * Perform an auto-tune operation. Sets up a limit cycle using the specified
 * tune effort. Averages the amplitude and period over the specified number of
 * cycles. This characterizes the process and determines the ultimate gain
 * and period, which are then used to calculate PID.
 *
 * CO(t) = P * [ e(t) + 1/Ti * (f e(t)dt) - Td * (d/dt PV(t)) ]
 *
 * Pu = 4/PI * tuneEffort / responseAmplitude
 * Ti = 0.5 * responsePeriod
 * Td = 0.125 * responsePeriod
 *
 * P = 0.6 * Pu
 * I = P * 1/Ti
 * D = P * Td
 */
static void
Pid_AutoTune(Pid *this, long period)
{
    hal_float_t                 error;

    // Calculate the error.
    error = *this->pCommand - *this->pFeedback;
    *this->pError = error;

    // Check if enabled and if still in tune mode.
    if(!*this->pEnable || !*this->pTuneMode){
        this->state = STATE_TUNE_ABORT;
    }

    switch(this->state){
    case STATE_TUNE_IDLE:
        // Wait for tune start command.
        if(*this->pTuneStart)
            this->state = STATE_TUNE_START;
        break;

    case STATE_TUNE_START:
        // Initialize tuning variables and start limit cycle.
        this->state = STATE_TUNE_POS;
        this->cycleCount = 0;
        this->cyclePeriod = 0;
        this->cycleAmplitude = 0;
        this->totalTime = 0;
        this->avgAmplitude = 0;
        *(this->ultimateGain) = 0;
        *(this->ultimatePeriod) = 0;
        *this->pOutput = *(this->bias) + fabs(*(this->tuneEffort));
        break;

    case STATE_TUNE_POS:
    case STATE_TUNE_NEG:
        this->cyclePeriod += period;

        if(error < 0.0){
            // Check amplitude.
            if(-error > this->cycleAmplitude)
                this->cycleAmplitude = -error;

            // Check for end of cycle.
            if(this->state == STATE_TUNE_POS){
                this->state = STATE_TUNE_NEG;
                Pid_CycleEnd(this);
            }

            // Update output so user can ramp effort until movement occurs.
            *this->pOutput = *(this->bias) - fabs(*(this->tuneEffort));
        }else{
            // Check amplitude.
            if(error > this->cycleAmplitude)
                this->cycleAmplitude = error;

            // Check for end of cycle.
            if(this->state == STATE_TUNE_NEG){
                this->state = STATE_TUNE_POS;
                Pid_CycleEnd(this);
            }

            // Update output so user can ramp effort until movement occurs.
            *this->pOutput = *(this->bias) + fabs(*(this->tuneEffort));
        }

        // Check if the last cycle just ended. This is really the number
        // of half cycles.
        if(this->cycleCount < *(this->tuneCycles))
            break;

        // Calculate PID.
        *(this->ultimateGain) = (4.0 * fabs(*(this->tuneEffort)))/(PI * this->avgAmplitude);
        *(this->ultimatePeriod) = 2.0 * this->totalTime / *(this->tuneCycles);
        *(this->ff0Gain) = 0;
        *(this->ff2Gain) = 0;

        if(*(this->tuneType) == TYPE_PID){
            // PID.
            *(this->pGain) = 0.6 * *(this->ultimateGain);
            *(this->iGain) = *(this->pGain) / (*(this->ultimatePeriod) / 2.0);
            *(this->dGain) = *(this->pGain) * (*(this->ultimatePeriod) / 8.0);
            *(this->ff1Gain) = 0;
        }else{
            // PI FF1.
            *(this->pGain) = 0.45 * *(this->ultimateGain);
            *(this->iGain) = *(this->pGain) / (*(this->ultimatePeriod) / 1.2);
            *(this->dGain) = 0;

            // Scaling must be set so PID output is in user units per second.
            *(this->ff1Gain) = 1;
        }

        // Fall through.

    case STATE_TUNE_ABORT:
    default:
        // Force output to zero.
        *this->pOutput = 0;

        // Abort any tuning cycle in progress.
        *this->pTuneStart = 0;
        this->state = (*this->pTuneMode)? STATE_TUNE_IDLE: STATE_PID;
    }
}



版权声明:本文为topwwl1原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。