Qt PID控制模拟程序

效果图
请添加图片描述

头文件#include “mainwindow.h”

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>

class QButtonGroup;

typedef struct _PID_PMT{

    float _ErrorVal;
    float _SetVal;
    float _KP;
    float _KI;
    float _KD;
    float _T;
    float _TS;
    float _OutOutP;

    float _ErrorSum;
    float _ErrorLast;

    float _CurrVal;
    float _OutVal;
    float _Item_KP;
    float _Item_KI;
    float _Item_KD;
    float _Item_PID;
    _PID_PMT(){
        _ErrorVal=0.0;
        _SetVal=0.0;
        _KP=0.0;
        _KI=0.0;
        _KD=0.0;
        _T=0.0;
        _TS=0.0;
        _OutOutP=0.0;

        _ErrorSum=0.0;
        _ErrorLast=0.0;

        _CurrVal=0.0;
        _OutVal=0.0;
        _Item_KP=0.0;
        _Item_KI=0.0;
        _Item_KD=0.0;
        _Item_PID=0.0;
    }
}_PID_PMT;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void fun_SetText();

public slots:
    void slots_btnChlickedStart();
    void slots_btnChlickedStop();
    void slots_editingFinished();
    void slots_RadioGroupChange(int id);
    void slots_TimeOut();
    void slots_CurveOffSet();
public:
    _PID_PMT m_PID_PMT;
    QTimer *m_Timer;
    QTimer *m_Timer_addData;
    double m_MaxKey;

    QButtonGroup *m_Btngroup;
    int m_RadId;
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

C文件#include “mainwindow.cpp”

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->subCurve->fun_intUi2();
    ui->subCurve->yAxis->setRange(-50,150);


    m_Btngroup=new QButtonGroup(this);

    ui->m_rad_Time->setChecked(true);
    ui->m_rad_Time->setObjectName("0");
    ui->m_rad_Val->setObjectName("1");
    m_Btngroup->addButton(ui->m_rad_Time,0);
    m_Btngroup->addButton(ui->m_rad_Val,1);
    //connect(m_Btngroup,static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked),this,&MainWindow::slots_RadioGroupChange);


    m_Timer=new QTimer;
    m_Timer_addData=new QTimer;
    connect(m_Timer,&QTimer::timeout,this,&MainWindow::slots_TimeOut);
    connect(m_Timer_addData,&QTimer::timeout,this,&MainWindow::slots_CurveOffSet);

    connect(ui->m_edtSetVal,&QLineEdit::editingFinished,this,&MainWindow::slots_editingFinished);
    connect(ui->m_edtKp,&QLineEdit::editingFinished,this,&MainWindow::slots_editingFinished);
    connect(ui->m_edtKi,&QLineEdit::editingFinished,this,&MainWindow::slots_editingFinished);
    connect(ui->m_edtKd,&QLineEdit::editingFinished,this,&MainWindow::slots_editingFinished);
    connect(ui->m_edtT,&QLineEdit::editingFinished,this,&MainWindow::slots_editingFinished);
    connect(ui->m_edtOutPutP,&QLineEdit::editingFinished,this,&MainWindow::slots_editingFinished);

    connect(ui->m_btnStart,&QPushButton::clicked,this,&MainWindow::slots_btnChlickedStart);
    connect(ui->m_btnStop,&QPushButton::clicked,this,&MainWindow::slots_btnChlickedStop);

    ui->m_edtSetVal->setText("100");
    ui->m_edtKp->setText("0.5");
    ui->m_edtKi->setText("0.5");
    ui->m_edtKd->setText("0.5");
    ui->m_edtT->setText("100");
    ui->m_edtOutPutP->setText("0.5");
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::fun_SetText()
{

}

void MainWindow::slots_btnChlickedStart()
{
    ui->m_rad_Val->setEnabled(false);
    ui->m_rad_Time->setEnabled(false);
    ui->m_btnStart->setEnabled(false);
    ui->m_btnStop->setEnabled(true);

    ui->subCurve->clearGraphs();
    ui->subCurve->fun_addGraph(0);
    ui->subCurve->fun_addGraph(1);
    m_Timer->start(m_PID_PMT._T);
    m_Timer_addData->start(m_PID_PMT._T+15);

    m_PID_PMT._ErrorSum=0.0;
    m_PID_PMT._ErrorLast=0.0;
    m_PID_PMT._CurrVal=0.0;

    QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
    dateTicker->setDateTimeFormat("MM-dd hh:mm:ss");
    dateTicker->setDateTimeSpec(Qt::LocalTime);
    QSharedPointer<QCPAxisTicker> ValTicker(new QCPAxisTicker);

    QRadioButton *btn=qobject_cast<QRadioButton *>(m_Btngroup->checkedButton());
    m_RadId=btn->objectName().toUInt();
    double CurrenTime_ms=QDateTime::currentMSecsSinceEpoch()/1000.0;
    m_MaxKey=0;
    switch (m_RadId)
    {
    case 0:
        dateTicker->setTickCount(5);
        ui->subCurve->xAxis->setTicker(dateTicker);
        ui->subCurve->xAxis->setRange(CurrenTime_ms-30,CurrenTime_ms+30);
        break;
    default:
        ValTicker->setTickCount(5);
        ui->subCurve->xAxis->setTicker(ValTicker);
        ui->subCurve->xAxis->setRange(0,100);
        break;
    }
}

void MainWindow::slots_btnChlickedStop()
{
    ui->m_rad_Val->setEnabled(true);
    ui->m_rad_Time->setEnabled(true);
    ui->m_btnStart->setEnabled(true);
    m_Timer->stop();
    m_Timer_addData->stop();
}

void MainWindow::slots_editingFinished()
{
    m_PID_PMT._SetVal=ui->m_edtSetVal->text().toFloat();
    m_PID_PMT._KP=ui->m_edtKp->text().toFloat();
    m_PID_PMT._KI=ui->m_edtKi->text().toFloat();
    m_PID_PMT._KD=ui->m_edtKd->text().toFloat();
    m_PID_PMT._T=ui->m_edtT->text().toFloat();
    m_PID_PMT._OutOutP=ui->m_edtOutPutP->text().toFloat();

    m_PID_PMT._TS=m_PID_PMT._T/1000.0;
}

void MainWindow::slots_RadioGroupChange(int id)
{

}

void MainWindow::slots_TimeOut()
{  
    //误差
    m_PID_PMT._ErrorVal=m_PID_PMT._SetVal-m_PID_PMT._CurrVal;
    //比例项
    m_PID_PMT._Item_KP=m_PID_PMT._KP*m_PID_PMT._ErrorVal;
    //积分项
    m_PID_PMT._ErrorSum+=m_PID_PMT._ErrorVal;
    if(m_PID_PMT._ErrorVal>m_PID_PMT._SetVal)
    {
        m_PID_PMT._ErrorSum=0;
    }
    m_PID_PMT._Item_KI=m_PID_PMT._KP*(m_PID_PMT._KI*m_PID_PMT._ErrorSum);
    //微分项
    if(m_MaxKey==0){
        m_PID_PMT._ErrorLast=m_PID_PMT._ErrorVal;
    }
    m_PID_PMT._Item_KD=m_PID_PMT._KP*(m_PID_PMT._KD*((m_PID_PMT._ErrorVal-m_PID_PMT._ErrorLast)/m_PID_PMT._TS));
    m_PID_PMT._ErrorLast=m_PID_PMT._ErrorVal;

    m_PID_PMT._Item_PID=m_PID_PMT._Item_KP+m_PID_PMT._Item_KI+m_PID_PMT._Item_KD;


    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    int rand =qrand()%10;
    double disturb=rand/100.0;

    float ResVal=m_PID_PMT._Item_PID*m_PID_PMT._OutOutP;
    m_PID_PMT._CurrVal+=ResVal;

    qDebug()<<"Error"<<m_PID_PMT._ErrorVal;
    qDebug()<<"P"<<m_PID_PMT._Item_KP;
    qDebug()<<"I"<<m_PID_PMT._Item_KI;
    qDebug()<<"D"<<m_PID_PMT._Item_KD;
    qDebug()<<"ResVal"<<ResVal<<endl;

    ui->m_edtCurrVal->setText(QString::number(m_PID_PMT._CurrVal,'f',4));
    ui->m_edtOutVal->setText(QString::number(ResVal,'f',4));

    ui->m_edtOut_PID->setText(QString::number(m_PID_PMT._Item_PID,'f',4));
    ui->m_edtOut_I->setText(QString::number(m_PID_PMT._Item_KI,'f',4));
    ui->m_edtOut_D->setText(QString::number(m_PID_PMT._Item_KD,'f',4));

    double CurrenTime_ms=QDateTime::currentMSecsSinceEpoch()/1000.0;
    m_MaxKey+=1;
    switch (m_RadId)
    {
    case 0:
        for(int i=0;i<ui->subCurve->graphCount();i++)
        {
            switch (i)
            {
            case 0:
                ui->subCurve->graph(0)->addData(CurrenTime_ms,m_PID_PMT._CurrVal);
                break;
            case 1:
                ui->subCurve->graph(i)->addData(CurrenTime_ms,m_PID_PMT._SetVal);
                break;
            default:
                break;
            }
        }
        break;
    default:
        for(int i=0;i<ui->subCurve->graphCount();i++)
        {
            switch (i)
            {
            case 0:
                ui->subCurve->graph(0)->addData(m_MaxKey,m_PID_PMT._CurrVal);
                break;
            case 1:
                ui->subCurve->graph(i)->addData(m_MaxKey,m_PID_PMT._SetVal);
                break;
            default:
                break;
            }
        }
        break;
    }

}

void MainWindow::slots_CurveOffSet()
{
    QCPRange xRand=ui->subCurve->xAxis->range();
    qint64 CurrenTime_s=QDateTime::currentMSecsSinceEpoch();
    double diffVal=double(CurrenTime_s/1000.0)-xRand.upper;
    switch (m_RadId)
    {
    case 0:
        if(diffVal>0)
        {
            ui->subCurve->xAxis->moveRange(diffVal);
        }
        break;
    default:
        if(m_MaxKey>xRand.upper){
           ui->subCurve->xAxis->setRange(xRand.lower,m_MaxKey);
        }
        break;
    }
    ui->subCurve->replot(QCustomPlot::rpQueuedReplot);
}

源码下载
链接: 源码下载

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值