Motor current controller
Fork of CURRENT_CONTROL by
CURRENT_CONTROL.cpp
- Committer:
- benson516
- Date:
- 2016-12-19
- Revision:
- 7:6794cfba3564
- Parent:
- 6:bae35ca64f10
- Child:
- 8:fd6fb3cb12ec
File content as of revision 7:6794cfba3564:
#include "mbed.h" #include "CURRENT_CONTROL.h" //=====================LPF ====================// LPF::LPF(float samplingTime, float cutOff_freq_Hz_in) { Ts = samplingTime; cutOff_freq_Hz = cutOff_freq_Hz_in; alpha_Ts = (2*3.1415926)*cutOff_freq_Hz*Ts; output = 0.0; // Flag_Init = false; } float LPF::filter(float input) { // Initialization if (!Flag_Init){ reset(input); Flag_Init = true; return output; } // output = (1.0 - alpha_Ts)*output + alpha_Ts*input; output += alpha_Ts*(input - output); return output; } void LPF::reset(float input) { // output = (1.0 - alpha_Ts)*output + alpha_Ts*input; output = input; return; } //================== CURRENT_CONTROL =================// CURRENT_CONTROL::CURRENT_CONTROL(PinName curChannel, PinName PwmChannel1, PinName PwmChannel2, PWMIndex pwmIndex, float Kp, float Ki, float Kd, float Ka, float samplingTime) : currentAnalogIn(curChannel), MotorPlus(PwmChannel1), MotorMinus(PwmChannel2), pid(Kp,Ki,Kd,samplingTime), lpFilter(samplingTime, 100.0), // 1.5915 Hz = 10 rad/s curFeedBack(0.0), curFeedBack_filter(0.0), voltage_out(0.0) { pwmIndex_ = pwmIndex; Ts = samplingTime; //setup motor PWM parameters MotorPlus.period_us(50); //set the pwm period = 50 us, where the frequency = 20kHz MotorPlus.write(0.5); //duty ratio = 0.5 in complementary output mode -> static if(pwmIndex_ == PWM1)TIM1->CCER |= 4; else if(pwmIndex_ == PWM2)TIM1->CCER |= 64; //enable complimentary output // Flag_Init = false; Init_count = 0; Accumulated_offset = 0.0; // currentOffset = 0.0; // delta_output = 0.0; // Set PID's parameters ///////////////////// pid.Kp = Kp; pid.Ki = Ki; pid.Kd = Kd; pid.Ka = Ka; // Gain for anti-windup // Ka = 0.0017 } void CURRENT_CONTROL::OffsetInit(void){ if (Flag_Init) return; // Init_count++; Accumulated_offset += GetAnalogIn(); if (Init_count >= 500){ // Fixed time currentOffset = Accumulated_offset/float(Init_count); Flag_Init = true; } } // void CURRENT_CONTROL::SetParams(float Analog2Cur, float angSpeed2BackEmf, float voltage2DutyRatio) { analog2Cur = Analog2Cur;//LTS25-NP current sensor working with STM32F446RE : 3.3*8/0.6 Ke = angSpeed2BackEmf; voltage2Duty = voltage2DutyRatio; } // float CURRENT_CONTROL::saturation(float input_value, float &delta, const float &limit_H, const float &limit_L){ if( input_value > limit_H ){ delta = limit_H - input_value; input_value = limit_H; }else if( input_value < limit_L ){ delta = limit_L - input_value; input_value = limit_L; }else{ delta = 0.0; } return input_value; } // void CURRENT_CONTROL::Control(float curRef, float angularSpeed) { // Init check OffsetInit(); if (!Flag_Init) return; ////////////////////////////////////// // Get measurement GetCurrent(); //--------------------------------// // PID pid.Compute_noWindUP(curRef, curFeedBack_filter); // Voltage output with back-emf compensation voltage_out = -pid.output + func_back_emf(angularSpeed); // Output saturation and unit changing SetPWMDuty( 0.5 + saturation( voltage_out*voltage2Duty, delta_output, 0.5, -0.5) ); //--------------------------------// // Anti-windup pid.Anti_windup(delta_output); } // Back emf as the function of rotational speed float CURRENT_CONTROL::func_back_emf(const float &W_in){ return (Ke*W_in); } //****************for test************************// void CURRENT_CONTROL::SetPWMDuty(float ratio) { MotorPlus = ratio; if(pwmIndex_ == PWM1){ TIM1->CCER |= 4; }else if(pwmIndex_ == PWM2){ TIM1->CCER |= 64; } } float CURRENT_CONTROL::GetAnalogIn(void) { analogInValue = currentAnalogIn.read(); return analogInValue; } float CURRENT_CONTROL::GetCurrent(void) { // Init check if (!Flag_Init) return 0.0; //-----------------------------------------// analogInValue = currentAnalogIn.read(); // Unit transformation curFeedBack = (analogInValue - currentOffset)*analog2Cur; // Low-pass filter curFeedBack_filter = lpFilter.filter(curFeedBack); return curFeedBack; //curFeedBack_filter; }