⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pid_gen1.cpp

📁 a program that generates a pulse-width modulated (PWM)signal.
💻 CPP
字号:
// Function definitions for the generic PID controller
// File: pid_gen1.cpp
// Created 10/5/95 by DM Auslander
// Modified 5/29/97, DM Auslander
// Uses a combination of global data and messages to avoid
//  the need for virtual functions.
// Does not use any state structure (control is either on or off)

#include <iostream.h>
#include <math.h>
#include "tasks.hpp"

PIDControl::PIDControl(char *name,double dtt,
            BaseTask *ActTask,int ActBox,
            BaseTask *ProcTask, int PrIndex,
            double aKp,double aKi,double aKd,double aMin,double aMax,
            double aSetpoint,int aControllerOn,
            int ProcNo)
                 : BaseTask (name,ProcNo)
     {
     dt = dtt;
     NextTaskTime = 0.0;
     set = aSetpoint;
     val = 0.0;    // Initial values
     integ = prev_set = prev_val = 0.0;
     kp = aKp;
     ki = aKi;
     kd = aKd;
     min = aMin;
     max = aMax;
     first = 1;
     ControllerOn = aControllerOn;
     ActuationTask = ActTask;
     ActuationBox = ActBox;
     ProcessTask = ProcTask;
     ProcValIndex = PrIndex;
     CreateGlobal(10);  // Create global data bases
     }
PIDControl::~PIDControl()
    {
    }

int PIDControl::Run (void) // Task function
    {
    double Time;
    double value;
    int flag;

    NumScans++; // Increment scan count
    if(!ControllerOn)
        {
        // No actuation is sent if controller is off --
        //   some other task is assumed to be handling that

        // Check for new gains. New gains can only be recognized
        //   when the controller is stopped. This could be changed
        //   by building a "bumpless" transfer into the controller.
        //   Otherwise, a gain change would put a large transient
        //   into the system.
        if(GetRTMessage(PID_START))
            {
            GetRTMessage(PID_STOP);  // Clear old STOP messages
            if(GetRTMessage(PID_NEWGAINS))
                {
                // Read new gains
                if(GetRTMessage(PID_KP,&flag,&value))kp = value;
                if(GetRTMessage(PID_KI,&flag,&value))ki = value;
                if(GetRTMessage(PID_KD,&flag,&value))kd = value;
                if(GetRTMessage(PID_MINV,&flag,&value))min = value;
                if(GetRTMessage(PID_MAXV,&flag,&value))max = value;
                }
            first = 1;  // Make sure PID behaves properly
                    // for its first run
            ControllerOn = 1;
            return(0);  // If an intermittent task,
                    // run again immediately
            }
        return(1);
        }

    if(GetRTMessage(PID_STOP))
        {
        ControllerOn = 0;  // Stop control
        return(1);
        }
    Time = GetTimeNow();
    if((Time >= NextTaskTime) || first)
        {
        //if(first)NextTaskTime = Time + dt;
        //else    NextTaskTime += dt;
        NextTaskTime = Time + dt;

        if(GetRTMessage(PID_SETPOINT,&flag,&value))set = value;
        val = GetGlobalData(ProcessTask,ProcValIndex);
        mc = PIDCalc(); // Do the PID calculation
        CopyGlobal();  // Make global information visible
        // Send out actuation value if this service has been
        //  requested.Otherwise, value can be obtained from the
        //  controller's global data
        if(ActuationTask != NULL)
            {
            // Send out the actuation value
            SendRTMessage(ActuationTask,ActuationBox,0,mc,MESSAGE_OVERWRITE);
            }
        first = 0;  // Not the first time anymore
        }
    return(1);     // Let task dispatcher go on to next task
    }

double PIDControl::PIDCalc(void) // Calculate the output of a PID controller
     // 'val' is the process variable value; 'set' is the setpoint
    {
    double m;    // Controller output
    double mpd;      // Portion of output due to P and D terms
    double itrial;       // Trial value for intergrator
    double err,prev_err;     // Errors
    double deriv;

    err = set - val;
    prev_err = prev_set - prev_val;     // Previous error
    if(first)deriv = 0.0;
    else deriv = kd * (err - prev_err) / dt;
    //else deriv = kd * (prev_val - val) / dt;

    mpd = kp * err + deriv;  // PD result only

    if(first)itrial = integ;  // Don't compute on first time
    else itrial = integ + ki * err * dt; // Trial value for integrator

    m = mpd + itrial;  // Trial controller result
    if((m <= max) && (m >= min))
        {
        // Controller is within limits
        integ = itrial;
        }
    else
        {
        // Controller is saturated
        // Leave integrator at its old value and bring output
        // within limits
        if(m > max)m = max;
        else m = min;
        }
    prev_set = set;
    prev_val = val;
    PrivateGlobalData[PID_ACTUATION] = m;
    PrivateGlobalData[PID_PROCESS] = val;
    PrivateGlobalData[PID_ERROR] = err;
    PrivateGlobalData[PID_SET] = set;
    return(m);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -