mbedのPIDライブラリを改良したものです 主な変更 ・PIDゲインを独立に調整可能 ・実行中に入力値と出力値の範囲を変更する機能の削除 ・微分制御に不完全微分を追加 ・PIDゲインを設定する機能を追加 ・各種ゲッターを削除
Dependents: Nucleo_MPU_9250_ test_master_kourobo2018 Nucleo_MPU_9250_
PIDcontroller.cpp
- Committer:
- porizou
- Date:
- 2016-02-01
- Revision:
- 0:eeb41e25a490
File content as of revision 0:eeb41e25a490:
#include "PIDcontroller.h" PID::PID(float Kp, float Ki, float Kd, float tSample){ tSample_ = tSample; Kp_ = Kp; Ki_ = Ki; Kd_ = Kd; setPoint_ = 0.0; processVariable_ = 0.0; controllerOutput_ = 0.0; prevControllerOutput_ = 0.0; accError_ = 0.0; Error_ = 0.0; prevError_= 0.0; Bias_ = 0.0; usingFeedForward = 0; usingIncompleteDifferential = 0; prevDiffOut = 0.0; u_ = 0.0; } void PID::setInputLimits(float inMin, float inMax){ if(inMin >= inMax) return; inMin_ = inMin; inMax_ = inMax; inSpan_ = inMax - inMin; } void PID::setOutputLimits(float outMin, float outMax){ if(outMin >= outMax) return; outMin_ = outMin; outMax_ = outMax; outSpan_ = outMax - outMin; } void PID::setBias(float Bias) { Bias_ = Bias; usingFeedForward = 1; } void PID::setIncompleteDifferential(float u) { u_ = u; usingIncompleteDifferential = 1; } void PID::setSetPoint(float sp){ setPoint_ = sp; } void PID::setProcessValue(float pv){ processVariable_ = pv; } void PID::setGain(float Kp, float Ki, float Kd) { Kp_ = Kp; Ki_ = Ki; Kd_ = Kd; } float PID::compute(){ //現在値と目標値の値を0~100%の範囲に置き換える float scaledPV = scaledParcent((processVariable_ - inMin_) / inSpan_); float scaledSP = scaledParcent((setPoint_ - inMin_) / inSpan_); //偏差の計算 Error_= scaledSP - scaledPV; //アンチワインドアップ if (!(prevControllerOutput_ >= 1 && Error_ > 0) && !(prevControllerOutput_ <= 0 && Error_ < 0)) { accError_ += (Error_ + prevError_) / 2.0 * tSample_; //偏差の積分値の計算 } //偏差の微分値の計算(不完全微分が有効な場合,偏差の不完全微分値を計算) float diffError = usingIncompleteDifferential ? calcIncompleteDifferential() : (Error_ - prevError_) / tSample_; //フィードフォワード制御が有効な場合,バイアス値の計算 float scaledBias = usingFeedForward ? (Bias_ - outMin_) / outSpan_ : 0.0; //PIDの計算 controllerOutput_ = scaledParcent(scaledBias + Kp_ * Error_ + Ki_ * accError_ + Kd_ * diffError); //出力の値,偏差の値を更新 prevControllerOutput_ = controllerOutput_; prevError_ = Error_; //微分項の値を更新 prevDiffOut = Kd_ * diffError; //PIDの出力を実際の値に変換して返す return ((controllerOutput_ * outSpan_) + outMin_); } float PID::scaledParcent(float value) { if(value > 1.0) { return 1.0; } else if(value < 0.0) { return 0.0; } else return value; } /** * 不完全微分の式 * * 伝達関数 * Yn = (Td*s / (1 + k*Td*s)) * E * * 差分の式 * yn = (k*Td / (Δt + k*Td)) * yn-1 + (Td / (Δt + k*Td))*(en - en-1) * * Δt 制御周期 * k 定数 * Td 微分ゲイン * yn 現在の出力 * yn-1 前回の出力 * en 現在の偏差 * en-1 前回の偏差 * * 参考文献 http://www.nikko-pb.co.jp/products/k_data/P12_13.pdf */ float PID::calcIncompleteDifferential(void) { float k = 1 / (tSample_ + u_ * Kd_); return (k * u_ * prevDiffOut) + (k * (Error_ - prevError_)); }