Custom version for NXP cup car
MotorControl.cpp
- Committer:
- Clarkk
- Date:
- 2017-07-05
- Revision:
- 3:170c22171ec2
- Parent:
- 2:0d5c994d8135
- Child:
- 4:66154ae82263
File content as of revision 3:170c22171ec2:
#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; motorACurrent[motorCurrentIndex] = MotA_ADCresult; motorBCurrent[motorCurrentIndex] = MotB_ADCresult; /* index = motorCurrentIndex; for(i=0;i<10;i++) { sum += motorACurrent[index] - motorBCurrent[index]; if(index == 0) index = MOTSAMPLECOUNT; index--; } torqueDiffAvg = sum;*/ } float Motors::getWheelRPS(char mot) { float current,meanVoltage; uint8_t index = motorCurrentIndex; // TODO: optimise computation time if(mot == 'A') { current = (float)motorACurrent[index]/1240.9; // *3.3/4095 meanVoltage = ((float)motorAPWM[index])/INT_MAX*(float)batteryVoltage[batVoltageIndex]/217.7; // *3.3/4095*5.7 } else { current = (float)motorBCurrent[index]/1240.9; // *3.3/4095 meanVoltage = ((float)motorBPWM[index])/INT_MAX*(float)batteryVoltage[batVoltageIndex]/217.7; // *3.3/4095*5.7 } // freeSpeed = 9.8004*meanVoltage-7.0023 // speed = (freeSpeed - (2.255*meanVoltage+10.51)*current) return ((9.8004*meanVoltage-7.0023)-(2.255*meanVoltage+10.51)*current); // rps } float Motors::getWheelSpeed(char mot) { return getWheelRPS(mot)*0.157; // in m/s (pi*0.05) } float Motors::getCarSpeed() { return (getWheelSpeed('A')+getWheelSpeed('B'))/2.0; } void Motors::setPWM(float value) { fixedPWM = (int16_t)(INT_MAX*value); } 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) // process data only if a new data is available { motorDriveIndex = motorCurrentIndex; 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) // compute MotA PWM /* if ((nextDelta > 0 && nextPWM < INT_MIN + nextDelta) || (nextDelta < 0 && nextPWM > INT_MAX + nextDelta)) motorAPWM[motorDriveIndex] = INT_MIN; else motorAPWM[motorDriveIndex] = nextPWM - nextDelta;*/ motorAPWM[motorDriveIndex] = nextPWM-nextDelta; // compute MotB PWM /* if (((nextDelta > 0) && (nextPWM > (INT_MAX - nextDelta))) || ((nextDelta < 0) && (nextPWM < (INT_MIN - nextDelta)))) motorBPWM[motorDriveIndex] = INT_MAX; else motorBPWM[motorDriveIndex] = nextPWM + nextDelta;*/ motorBPWM[motorDriveIndex] = nextPWM+nextDelta; currentMotAPWM = ((float)motorAPWM[motorDriveIndex])/INT_MAX; currentMotBPWM = ((float)motorBPWM[motorDriveIndex])/INT_MAX; TFC_SetMotorPWM(currentMotAPWM,currentMotBPWM); } } float Motors::getAverageMotCurrent(char mot) { uint8_t i; uint32_t 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 ((float)sum)/MOTSAMPLECOUNT/1240.9; } float Motors::getMotCurrent(char mot) { if(mot == 'A') return (float)motorACurrent[motorCurrentIndex]/1240.9; else return (float)motorBCurrent[motorCurrentIndex]/1240.9; } float Motors::getMotPWM(char mot) { if(mot == 'A') return currentMotAPWM; else return currentMotBPWM; } 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) { nextPWM = (int16_t)(pwm*INT_MAX); } void Motors::setSpeedTargetValue(float speed) { speedTarget = (int32_t)(speed*1e6); } float Motors::getSpeedError() { return ((float)speederror1000000)/1e6; }