Custom version for NXP cup car
MotorControl.cpp
- Committer:
- Clarkk
- Date:
- 2019-02-20
- Revision:
- 4:66154ae82263
- Parent:
- 3:170c22171ec2
File content as of revision 4:66154ae82263:
#include "TFC.h" #include "MotorControl.h" //#include "limits.h" #define INT_MAX 32767 #define INT_MIN -32768 Motors::Motors() { uint8_t i; PWMRegulatedMode = false; motorCurrentIndex = 0; batVoltageIndex = 0; for(i=0;i<MOTSAMPLECOUNT;i++) { motorACurrent[i] = 0; motorBCurrent[i] = 0; motorAPWM[i] = 0; motorAPWM[i] = 0; } } void Motors::start() { TFC_HBRIDGE_ENABLE; } void Motors::stop() { TFC_HBRIDGE_DISABLE; } void Motors::saveBatteryVoltageMeasure(uint16_t ADCresult) { batVoltageIndex++; if(batVoltageIndex >= BATSAMPLECOUNT) batVoltageIndex = 0; batteryVoltage[batVoltageIndex] = ADCresult; } void Motors::saveMotorCurrentMeasure(uint16_t MotA_ADCresult, uint16_t MotB_ADCresult) { // uint8_t i,index; // int16_t sum = 0; motorCurrentIndex++; if(motorCurrentIndex >= MOTSAMPLECOUNT) motorCurrentIndex = 0; // current is always measured as positive. Need to check direction of motor drive to know the sign // current value stored is directly value in volt at input of ADC, not real current in Amp if(currentMotAPWM >= 0) motorACurrent[motorCurrentIndex] = (float)MotA_ADCresult/1240.9090; // *3.3/4095 else motorACurrent[motorCurrentIndex] = -(float)MotA_ADCresult/1240.9090; // *3.3/4095 if(currentMotBPWM >= 0) motorBCurrent[motorCurrentIndex] = (float)MotB_ADCresult/1240.9090; // *3.3/4095 else motorBCurrent[motorCurrentIndex] = -(float)MotB_ADCresult/1240.9090; // *3.3/4095 motorAPWM[motorCurrentIndex] = currentMotAPWM; motorBPWM[motorCurrentIndex] = currentMotBPWM; /* index = motorCurrentIndex; for(i=0;i<10;i++) { sum += motorACurrent[index] - motorBCurrent[index]; if(index == 0) index = MOTSAMPLECOUNT; index--; } torqueDiffAvg = sum;*/ } float Motors::getAverageSpeed() { float currentA = 0, currentB = 0, meanVoltageA = 0, meanVoltageB = 0; uint8_t index = motorCurrentIndex; uint8_t i,avg = 10; for(i=0;i<avg;i++) { currentA += motorACurrent[index]; meanVoltageA += ((float)motorAPWM[index])*(float)batteryVoltage[batVoltageIndex]; // *3.3/4095*5.7 currentB += motorBCurrent[index]; meanVoltageB += ((float)motorBPWM[index])*(float)batteryVoltage[batVoltageIndex]; // *3.3/4095*5.7 if(index == 0) index = MOTSAMPLECOUNT; index--; } // freeSpeed = 9.8004*meanVoltage-7.0023 // speed = (freeSpeed - (2.255*meanVoltage+10.51)*current) return (((9.8004/INT_MAX/217.7*meanVoltageA-7.0023)-(2.255/INT_MAX/217.7*meanVoltageA+10.51)*currentA)+((9.8004/INT_MAX/217.7*meanVoltageB-7.0023)-(2.255/INT_MAX/217.7*meanVoltageB+10.51)*currentB))/avg/2*0.157; // m/s } float Motors::getWheelRPS(char mot) { float current,meanVoltage; uint8_t index = motorCurrentIndex; // TODO: optimise computation time if(mot == 'A') { meanVoltage = ((float)motorAPWM[index])/INT_MAX*(float)batteryVoltage[batVoltageIndex]/217.7; // *3.3/4095*5.7 return ((9.829651257*meanVoltage)-(19.33709258*motorACurrent[index])-6.435176945); } else { meanVoltage = ((float)motorBPWM[index])/INT_MAX*(float)batteryVoltage[batVoltageIndex]/217.7; // *3.3/4095*5.7 return ((9.829651257*meanVoltage)-(19.33709258*motorBCurrent[index])-6.435176945); } } float Motors::getWheelSpeed(char mot) { return getWheelRPS(mot)*0.15707963267; // in m/s (pi*0.05) } float Motors::getCarSpeed() { return (getWheelSpeed('A')+getWheelSpeed('B'))/2.0; } void Motors::setFixedPWMMode(void) { PWMRegulatedMode = false; } void Motors::setRegulatedPWMMode(void) { PWMRegulatedMode = true; } void Motors::processTasks() { int16_t nextDelta; int32_t torqueDiffAvg,PWMSumAvg,motorSumAvg,meanVoltage,nextp; uint8_t i,index; if(motorDriveIndex != ((motorCurrentIndex+1)%MOTSAMPLECOUNT)) // process data only if a new data is available { motorDriveIndex = motorCurrentIndex+1; // current is saved with the PWM, compute the next PWM now torqueDiffAvg = 0; PWMSumAvg = 0; motorSumAvg = 0; index = motorDriveIndex; // TODO: verify indexes for(i=0;i<10;i++) { // compute average values over 10 last measures torqueDiffAvg += motorACurrent[index] - motorBCurrent[index]; PWMSumAvg += motorAPWM[index]+motorBPWM[index]; motorSumAvg += motorACurrent[index]+motorBCurrent[index]; if(index == 0) index = MOTSAMPLECOUNT; index--; } if(PWMRegulatedMode) { /* a0 = 1000000; a1 = 93; // 10/a0/9.8004/pi/0.05*2*INT_MAX/3.3*4095/5.7; a2 = 1099919; // a0*7.0023*pi*0.05; a3 = 9996209; // 10/a0/2.255/pi/0.05*2*INT_MAX/3.3*4095/5.7/3.3*4095*2*10; a4 = 67; // a0*10.51*pi*0.05*3.3/4095/2/10; */ // compute current speed to get error when compared to target meanVoltage = PWMSumAvg*batteryVoltage[batVoltageIndex]; // speederror1000000 = meanVoltage/a1-a2-(meanVoltage/a3+a4)*motorSumAvg - speedTarget*a0; speederror1000000 = meanVoltage/93-1099919-(meanVoltage/9996209+67)*motorSumAvg - speedTarget; /*nextp = speederror1000000/-20; if(nextp > INT_MAX) nextPWM = INT_MAX; else if (nextp < INT_MIN) nextPWM = INT_MIN; else nextPWM = (int16_t)nextp; nextDelta = 0;*/ } else { nextPWM = fixedPWM; // 14745 } nextDelta = (int16_t)(torqueDiffAvg/2); // delta to apply is about half the sum (0x7fff/(10*1240.9)/5) nextDelta = 0; // compute MotA PWM /* if ((nextDelta > 0 && nextPWM < INT_MIN + nextDelta) || (nextDelta < 0 && nextPWM > INT_MAX + nextDelta)) currentMotAPWM = INT_MIN; else currentMotAPWM = nextPWM - nextDelta;*/ currentMotAPWM = nextPWM-nextDelta; // compute MotB PWM /* if (((nextDelta > 0) && (nextPWM > (INT_MAX - nextDelta))) || ((nextDelta < 0) && (nextPWM < (INT_MIN - nextDelta)))) currentMotBPWM = INT_MAX; else currentMotBPWM = nextPWM + nextDelta;*/ currentMotBPWM = nextPWM+nextDelta; TFC_SetMotorPWM(getMotPWM('A'),getMotPWM('B')); } } float Motors::getAverageMotCurrent(char mot) { uint8_t i; float sum = 0; if(mot == 'A') { for(i=0;i<MOTSAMPLECOUNT;i++) { sum += motorACurrent[i]; } } else { for(i=0;i<MOTSAMPLECOUNT;i++) { sum += motorBCurrent[i]; } } return sum/MOTSAMPLECOUNT; } float Motors::getMotCurrent(char mot) { if(mot == 'A') return motorACurrent[motorCurrentIndex]; else return motorBCurrent[motorCurrentIndex]; } float Motors::getMotPWM(char mot) { if(mot == 'A') return ((float)currentMotAPWM)/INT_MAX; else return ((float)currentMotBPWM)/INT_MAX; } float Motors::getAverageBatteryVoltage() { uint8_t i; uint32_t sum = 0; for(i=0;i<BATSAMPLECOUNT;i++) { sum += batteryVoltage[i]; } return ((float)sum)/BATSAMPLECOUNT/217.7; } void Motors::setFixedPWMValue(float pwm) { fixedPWM = (int16_t)(pwm*INT_MAX); } void Motors::setSpeedTargetValue(float speed) { speedTarget = (int32_t)(speed*1e6); } float Motors::getSpeedError() { return ((float)speederror1000000)/1e6; }