NXP cup car code made by Pascal. "stable" version apr. 2016
Dependencies: mbed FRDM-TFC PIDcontroller FreescaleIAP Vision MMA8451Q MotorControl
main.cpp@2:eb79d6e3f701, 2017-07-05 (annotated)
- Committer:
- Clarkk
- Date:
- Wed Jul 05 20:31:26 2017 +0000
- Revision:
- 2:eb79d6e3f701
- Parent:
- 1:5402c62ad487
- Child:
- 3:c21068661635
Nice version with some code cleaning.; Car is quite fast, slow down when error is high and accelerate then.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Clarkk | 0:5e090fec6099 | 1 | #include "mbed.h" |
Clarkk | 0:5e090fec6099 | 2 | #include "TFC.h" |
Clarkk | 0:5e090fec6099 | 3 | #include "MotorControl.h" |
Clarkk | 0:5e090fec6099 | 4 | #include "Vision.h" |
Clarkk | 0:5e090fec6099 | 5 | #include "MMA8451Q.h" |
Clarkk | 1:5402c62ad487 | 6 | #include "PIDcontroller.h" |
Clarkk | 0:5e090fec6099 | 7 | |
Clarkk | 0:5e090fec6099 | 8 | Serial pc(USBTX,USBRX); |
Clarkk | 0:5e090fec6099 | 9 | Serial debug(PTD3,PTD2); |
Clarkk | 0:5e090fec6099 | 10 | Ticker convTicker,batLevelTicker; |
Clarkk | 0:5e090fec6099 | 11 | Timeout camExpoTimeout; |
Clarkk | 0:5e090fec6099 | 12 | Timer t; |
Clarkk | 0:5e090fec6099 | 13 | Motors motors; |
Clarkk | 0:5e090fec6099 | 14 | Vision vision; |
Clarkk | 1:5402c62ad487 | 15 | PID steeringPID; |
Clarkk | 0:5e090fec6099 | 16 | |
Clarkk | 0:5e090fec6099 | 17 | uint32_t convCounter = 0; |
Clarkk | 0:5e090fec6099 | 18 | |
Clarkk | 0:5e090fec6099 | 19 | float getSteeringValue(float pixelIndex) |
Clarkk | 0:5e090fec6099 | 20 | { |
Clarkk | 1:5402c62ad487 | 21 | // return steering angle to send to servo function of pixel target |
Clarkk | 0:5e090fec6099 | 22 | return ((-5e-6*pixelIndex+0.0009)*pixelIndex-0.0248)*pixelIndex-0.9129; |
Clarkk | 0:5e090fec6099 | 23 | //return ((-5e-6*pixelIndex+0.0009)*pixelIndex-0.0224)*pixelIndex-0.9218; |
Clarkk | 0:5e090fec6099 | 24 | } |
Clarkk | 0:5e090fec6099 | 25 | |
Clarkk | 0:5e090fec6099 | 26 | float flt[4]={0,0,0,0}; |
Clarkk | 0:5e090fec6099 | 27 | float steeringFilter(float x) |
Clarkk | 0:5e090fec6099 | 28 | { |
Clarkk | 0:5e090fec6099 | 29 | return 2.0*x; |
Clarkk | 0:5e090fec6099 | 30 | |
Clarkk | 0:5e090fec6099 | 31 | /* uint8_t i; |
Clarkk | 0:5e090fec6099 | 32 | |
Clarkk | 0:5e090fec6099 | 33 | for(i=3;i>0;i--) |
Clarkk | 0:5e090fec6099 | 34 | { |
Clarkk | 0:5e090fec6099 | 35 | flt[i] = flt[i-1]; |
Clarkk | 0:5e090fec6099 | 36 | } |
Clarkk | 0:5e090fec6099 | 37 | flt[0] = x; |
Clarkk | 0:5e090fec6099 | 38 | |
Clarkk | 0:5e090fec6099 | 39 | return (flt[0]+flt[1]*0.75+flt[2]*0.5+flt[3]*0.25)/2.5;*/ |
Clarkk | 0:5e090fec6099 | 40 | } |
Clarkk | 0:5e090fec6099 | 41 | |
Clarkk | 0:5e090fec6099 | 42 | void applySteeringCommand(float value) |
Clarkk | 0:5e090fec6099 | 43 | { |
Clarkk | 0:5e090fec6099 | 44 | float clamp = 0.55; |
Clarkk | 0:5e090fec6099 | 45 | if(value > clamp) |
Clarkk | 0:5e090fec6099 | 46 | value = clamp; |
Clarkk | 0:5e090fec6099 | 47 | if(value < -clamp) |
Clarkk | 0:5e090fec6099 | 48 | value = -clamp; |
Clarkk | 0:5e090fec6099 | 49 | TFC_SetServo(0,value); |
Clarkk | 0:5e090fec6099 | 50 | } |
Clarkk | 0:5e090fec6099 | 51 | |
Clarkk | 0:5e090fec6099 | 52 | void stopCameraExposure() |
Clarkk | 0:5e090fec6099 | 53 | { |
Clarkk | 0:5e090fec6099 | 54 | } |
Clarkk | 0:5e090fec6099 | 55 | |
Clarkk | 2:eb79d6e3f701 | 56 | void dataConvertionRoutine() |
Clarkk | 0:5e090fec6099 | 57 | { |
Clarkk | 0:5e090fec6099 | 58 | uint8_t mask; |
Clarkk | 0:5e090fec6099 | 59 | |
Clarkk | 0:5e090fec6099 | 60 | // convertion of motor current is done at each tick |
Clarkk | 0:5e090fec6099 | 61 | mask = ADC_MASK_CAPTURE_MOTOR_CURRENT; |
Clarkk | 0:5e090fec6099 | 62 | |
Clarkk | 0:5e090fec6099 | 63 | // convertion of line scan is done each 5 ticks |
Clarkk | 0:5e090fec6099 | 64 | if((convCounter % 5) == 0) |
Clarkk | 0:5e090fec6099 | 65 | mask |= ADC_MASK_CAPTURE_LINE_SCAN; |
Clarkk | 0:5e090fec6099 | 66 | |
Clarkk | 0:5e090fec6099 | 67 | // convertion of pot and battery is done each 5 ticks |
Clarkk | 0:5e090fec6099 | 68 | if((convCounter % 5) == 2) |
Clarkk | 0:5e090fec6099 | 69 | mask |= ADC_MASK_CAPTURE_POT_0 | ADC_MASK_CAPTURE_POT_1 | ADC_MASK_CAPTURE_BATTERY_LEVEL; |
Clarkk | 0:5e090fec6099 | 70 | |
Clarkk | 0:5e090fec6099 | 71 | TFC_StartDataAcquisition(mask); |
Clarkk | 0:5e090fec6099 | 72 | |
Clarkk | 0:5e090fec6099 | 73 | convCounter++; |
Clarkk | 0:5e090fec6099 | 74 | if(convCounter == 4000000000) |
Clarkk | 0:5e090fec6099 | 75 | convCounter = 0; |
Clarkk | 0:5e090fec6099 | 76 | |
Clarkk | 0:5e090fec6099 | 77 | //TFC_StartDataAcquisition(ADC_MASK_CAPTURE_ALL); |
Clarkk | 0:5e090fec6099 | 78 | //camExpoTimeout.attach(&stopCameraExposure,camExposure); |
Clarkk | 0:5e090fec6099 | 79 | } |
Clarkk | 0:5e090fec6099 | 80 | |
Clarkk | 0:5e090fec6099 | 81 | void updateBatteryLevel() |
Clarkk | 0:5e090fec6099 | 82 | { |
Clarkk | 0:5e090fec6099 | 83 | float batteryVoltage; |
Clarkk | 0:5e090fec6099 | 84 | batteryVoltage = motors.getAverageBatteryVoltage(); |
Clarkk | 0:5e090fec6099 | 85 | TFC_SetBatteryLED_Level(batteryVoltage*3.3-18.8); |
Clarkk | 0:5e090fec6099 | 86 | } |
Clarkk | 0:5e090fec6099 | 87 | |
Clarkk | 0:5e090fec6099 | 88 | void saveADCMeas() |
Clarkk | 0:5e090fec6099 | 89 | { |
Clarkk | 0:5e090fec6099 | 90 | //TFC_BAT_LED2_TOGGLE; |
Clarkk | 0:5e090fec6099 | 91 | if(TFC_MotorCurrentReady) |
Clarkk | 0:5e090fec6099 | 92 | { |
Clarkk | 0:5e090fec6099 | 93 | TFC_MotorCurrentReady = 0; |
Clarkk | 0:5e090fec6099 | 94 | motors.saveMotorCurrentMeasure(TFC_ReadMotACurrentRaw(),TFC_ReadMotBCurrentRaw()); |
Clarkk | 0:5e090fec6099 | 95 | } |
Clarkk | 0:5e090fec6099 | 96 | if(TFC_LineScanImageReady) |
Clarkk | 0:5e090fec6099 | 97 | { |
Clarkk | 0:5e090fec6099 | 98 | TFC_LineScanImageReady = 0; // clear counter to be able to detect next frame |
Clarkk | 0:5e090fec6099 | 99 | vision.saveData((uint16_t*)TFC_LineScanImage0); |
Clarkk | 0:5e090fec6099 | 100 | } |
Clarkk | 0:5e090fec6099 | 101 | if(TFC_BatteryVoltageReady) |
Clarkk | 0:5e090fec6099 | 102 | { |
Clarkk | 0:5e090fec6099 | 103 | TFC_BatteryVoltageReady = 0; |
Clarkk | 0:5e090fec6099 | 104 | motors.saveBatteryVoltageMeasure(TFC_ReadBatteryVoltageRaw()); |
Clarkk | 0:5e090fec6099 | 105 | } |
Clarkk | 0:5e090fec6099 | 106 | } |
Clarkk | 0:5e090fec6099 | 107 | |
Clarkk | 0:5e090fec6099 | 108 | int main() |
Clarkk | 0:5e090fec6099 | 109 | { |
Clarkk | 2:eb79d6e3f701 | 110 | uint8_t i; |
Clarkk | 0:5e090fec6099 | 111 | uint8_t r,l; |
Clarkk | 2:eb79d6e3f701 | 112 | float motorPWM,steering,steeringFiltered; |
Clarkk | 0:5e090fec6099 | 113 | float pixelTarget; |
Clarkk | 0:5e090fec6099 | 114 | struct lineScanData lineData; |
Clarkk | 0:5e090fec6099 | 115 | uint32_t lastcount = 0; |
Clarkk | 0:5e090fec6099 | 116 | bool debugon = false; |
Clarkk | 0:5e090fec6099 | 117 | |
Clarkk | 0:5e090fec6099 | 118 | //MMA8451Q acc(PTE25, PTE24, (0x1d<<1)); |
Clarkk | 0:5e090fec6099 | 119 | |
Clarkk | 0:5e090fec6099 | 120 | TFC_Init(); |
Clarkk | 0:5e090fec6099 | 121 | |
Clarkk | 0:5e090fec6099 | 122 | pc.baud(115200); |
Clarkk | 0:5e090fec6099 | 123 | debug.baud(115200); |
Clarkk | 0:5e090fec6099 | 124 | |
Clarkk | 2:eb79d6e3f701 | 125 | // run convertion routine each 2ms |
Clarkk | 2:eb79d6e3f701 | 126 | convTicker.attach_us(&dataConvertionRoutine, 2000); |
Clarkk | 2:eb79d6e3f701 | 127 | // record data when convertion done |
Clarkk | 0:5e090fec6099 | 128 | TFC_ConvertionReadyCallback.attach(&saveADCMeas); |
Clarkk | 0:5e090fec6099 | 129 | |
Clarkk | 0:5e090fec6099 | 130 | batLevelTicker.attach(&updateBatteryLevel,0.2); |
Clarkk | 0:5e090fec6099 | 131 | |
Clarkk | 2:eb79d6e3f701 | 132 | motors.setFixedPWMMode(); |
Clarkk | 0:5e090fec6099 | 133 | motors.setSpeedTargetValue(2.0); |
Clarkk | 2:eb79d6e3f701 | 134 | motors.setPWM(0.45); |
Clarkk | 1:5402c62ad487 | 135 | |
Clarkk | 1:5402c62ad487 | 136 | steeringPID.setReference(0); |
Clarkk | 2:eb79d6e3f701 | 137 | steeringPID.setCoefficients(1.5,0,0); |
Clarkk | 1:5402c62ad487 | 138 | steeringPID.setOutputLimits(-0.6,0.6); |
Clarkk | 0:5e090fec6099 | 139 | |
Clarkk | 0:5e090fec6099 | 140 | while(1) |
Clarkk | 0:5e090fec6099 | 141 | { |
Clarkk | 0:5e090fec6099 | 142 | if(TFC_ReadPushButton(0)) |
Clarkk | 0:5e090fec6099 | 143 | { |
Clarkk | 0:5e090fec6099 | 144 | motors.stop(); |
Clarkk | 0:5e090fec6099 | 145 | debugon = false; |
Clarkk | 0:5e090fec6099 | 146 | } |
Clarkk | 0:5e090fec6099 | 147 | |
Clarkk | 0:5e090fec6099 | 148 | if(TFC_ReadPushButton(1)) |
Clarkk | 0:5e090fec6099 | 149 | { |
Clarkk | 0:5e090fec6099 | 150 | motors.start(); |
Clarkk | 0:5e090fec6099 | 151 | debugon = true; |
Clarkk | 0:5e090fec6099 | 152 | } |
Clarkk | 0:5e090fec6099 | 153 | |
Clarkk | 0:5e090fec6099 | 154 | vision.processTasks(); |
Clarkk | 0:5e090fec6099 | 155 | lineData = vision.getRoadData(); |
Clarkk | 0:5e090fec6099 | 156 | r = lineData.rightEdgeIndex; |
Clarkk | 0:5e090fec6099 | 157 | //if(r>=115) |
Clarkk | 0:5e090fec6099 | 158 | // r = 128; |
Clarkk | 0:5e090fec6099 | 159 | l = lineData.leftEdgeIndex; |
Clarkk | 0:5e090fec6099 | 160 | //if(l<=13) |
Clarkk | 0:5e090fec6099 | 161 | // l = 0; |
Clarkk | 0:5e090fec6099 | 162 | pixelTarget = (r+l)/2.0; |
Clarkk | 0:5e090fec6099 | 163 | /*if(pixelTarget < 63.5) |
Clarkk | 0:5e090fec6099 | 164 | pixelTarget -= (63.5-l)*0.1; |
Clarkk | 0:5e090fec6099 | 165 | else |
Clarkk | 0:5e090fec6099 | 166 | pixelTarget += (r-63.5)*0.1;*/ |
Clarkk | 1:5402c62ad487 | 167 | |
Clarkk | 0:5e090fec6099 | 168 | steering = getSteeringValue(pixelTarget); |
Clarkk | 1:5402c62ad487 | 169 | |
Clarkk | 1:5402c62ad487 | 170 | // previous |
Clarkk | 1:5402c62ad487 | 171 | //applySteeringCommand(steeringFilter(steering)); |
Clarkk | 1:5402c62ad487 | 172 | |
Clarkk | 1:5402c62ad487 | 173 | |
Clarkk | 1:5402c62ad487 | 174 | // new |
Clarkk | 2:eb79d6e3f701 | 175 | steeringFiltered = steeringPID.processNewValue(steering); |
Clarkk | 2:eb79d6e3f701 | 176 | applySteeringCommand(steeringFiltered); |
Clarkk | 2:eb79d6e3f701 | 177 | motorPWM = 0.6-abs(steeringFiltered)/2.0; |
Clarkk | 2:eb79d6e3f701 | 178 | motors.setPWM(motorPWM); |
Clarkk | 0:5e090fec6099 | 179 | |
Clarkk | 0:5e090fec6099 | 180 | motors.processTasks(); |
Clarkk | 0:5e090fec6099 | 181 | //motorPWM = TFC_ReadPot(0); |
Clarkk | 0:5e090fec6099 | 182 | //motorPWM = (TFC_GetDIP_Switch()*0.05+0.25); |
Clarkk | 0:5e090fec6099 | 183 | //motors.setFixedPWMValue(motorPWM); |
Clarkk | 0:5e090fec6099 | 184 | |
Clarkk | 0:5e090fec6099 | 185 | /*if(TFC_LineScanImageReady) |
Clarkk | 0:5e090fec6099 | 186 | { |
Clarkk | 0:5e090fec6099 | 187 | TFC_LineScanImageReady = 0; // clear counter to be able to detect next frame |
Clarkk | 0:5e090fec6099 | 188 | |
Clarkk | 0:5e090fec6099 | 189 | // calculation time measure |
Clarkk | 0:5e090fec6099 | 190 | t.reset(); |
Clarkk | 0:5e090fec6099 | 191 | t.start(); |
Clarkk | 0:5e090fec6099 | 192 | |
Clarkk | 0:5e090fec6099 | 193 | // stop calculation time measurement |
Clarkk | 0:5e090fec6099 | 194 | t.stop(); |
Clarkk | 0:5e090fec6099 | 195 | |
Clarkk | 0:5e090fec6099 | 196 | //pc.printf("Bat: %fV, PWM:%f, MA:%frps, MB:%frps\r",motors.getAverageBatteryVoltage(),motorPWM,motors.getWheelRPS('A'),motors.getWheelRPS('B')); |
Clarkk | 0:5e090fec6099 | 197 | //pc.printf("Bat: %fV, PWM:%f, MA:%fV, MB:%fV\r",motors.getAverageBatteryVoltage(),motorPWM,motors.getAverageMotCurrent('A'),motors.getAverageMotCurrent('B')); |
Clarkk | 0:5e090fec6099 | 198 | //pc.printf("Bat: %fV, PWM:%f, MotA:%f, MotB:%f, speedA:%f, speedB:%f\r",TFC_ReadBatteryVoltage(),motorPWM,TFC_ReadMotACurrent(),TFC_ReadMotBCurrent(),getMotSpeed('A',motorPWM),getMotSpeed('B',motorPWM)); |
Clarkk | 0:5e090fec6099 | 199 | //pc.printf("Bat: %fV, d=%f, time:%dus max light:%d @ %d \r",TFC_ReadBatteryVoltage(),steering,t.read_us(),lineData.maxLightValue,lineData.mostWhiteIndex); |
Clarkk | 0:5e090fec6099 | 200 | }*/ |
Clarkk | 0:5e090fec6099 | 201 | |
Clarkk | 1:5402c62ad487 | 202 | if((convCounter % 100) == 0) // each 0.2 second |
Clarkk | 0:5e090fec6099 | 203 | { |
Clarkk | 0:5e090fec6099 | 204 | //pc.printf("%d %d %d %d %d %d %d %d %d\r\n",TFC_LineScanImage0[0],TFC_LineScanImage0[15],TFC_LineScanImage0[31],TFC_LineScanImage0[47],TFC_LineScanImage0[63],TFC_LineScanImage0[79],TFC_LineScanImage0[95],TFC_LineScanImage0[111],TFC_LineScanImage0[127]); |
Clarkk | 0:5e090fec6099 | 205 | |
Clarkk | 0:5e090fec6099 | 206 | //pc.printf("["); |
Clarkk | 0:5e090fec6099 | 207 | //for(i=0;i<leftEdgeIndex;i++) pc.printf(" "); |
Clarkk | 0:5e090fec6099 | 208 | //pc.printf("^"); |
Clarkk | 0:5e090fec6099 | 209 | //for(i=leftEdgeIndex;i<mostWhiteIndex;i++) pc.printf(" "); |
Clarkk | 0:5e090fec6099 | 210 | //pc.printf("|"); |
Clarkk | 0:5e090fec6099 | 211 | //for(i=mostWhiteIndex;i<rightEdgeIndex;i++) pc.printf(" "); |
Clarkk | 0:5e090fec6099 | 212 | //pc.printf("^"); |
Clarkk | 0:5e090fec6099 | 213 | //for(i=rightEdgeIndex;i<128;i++) pc.printf(" "); |
Clarkk | 0:5e090fec6099 | 214 | //pc.printf("]\r\n"); |
Clarkk | 0:5e090fec6099 | 215 | |
Clarkk | 1:5402c62ad487 | 216 | pc.printf("%d %d => %f\r\n",l,r,steering); |
Clarkk | 1:5402c62ad487 | 217 | |
Clarkk | 1:5402c62ad487 | 218 | /*for(i=0;i<128;i++) |
Clarkk | 0:5e090fec6099 | 219 | { |
Clarkk | 0:5e090fec6099 | 220 | pc.printf("%d ",TFC_LineScanImage0[i]); |
Clarkk | 0:5e090fec6099 | 221 | } |
Clarkk | 1:5402c62ad487 | 222 | pc.printf("\r\n");*/ |
Clarkk | 1:5402c62ad487 | 223 | } |
Clarkk | 0:5e090fec6099 | 224 | |
Clarkk | 0:5e090fec6099 | 225 | //pc.printf("%d %f %f %f \r",lastcount,acc.getAccX(),acc.getAccY(),acc.getAccZ()); |
Clarkk | 0:5e090fec6099 | 226 | if(debugon && (convCounter != lastcount)) |
Clarkk | 0:5e090fec6099 | 227 | { |
Clarkk | 0:5e090fec6099 | 228 | lastcount = convCounter; |
Clarkk | 1:5402c62ad487 | 229 | //debug.printf("%d %f %f %f\n",lastcount,motors.getCarSpeed(),motors.getSpeedError(),steering); |
Clarkk | 0:5e090fec6099 | 230 | //debug.printf("%d %f %f %f\n",lastcount,motors.getWheelSpeed('A'),motors.getWheelSpeed('B'),steering); |
Clarkk | 0:5e090fec6099 | 231 | //debug.printf("%d %f %f %f\n",lastcount,motors.getMotCurrent('A'),motors.getMotCurrent('B'),steering); |
Clarkk | 0:5e090fec6099 | 232 | //debug.printf("%d %f %f %f\n",lastcount,motors.getMotPWM('A'),motors.getMotPWM('B'),steering); |
Clarkk | 0:5e090fec6099 | 233 | //debug.printf("%d %f %f %f\n",lastcount,acc.getAccX(),acc.getAccY(),steering); |
Clarkk | 0:5e090fec6099 | 234 | } |
Clarkk | 0:5e090fec6099 | 235 | } |
Clarkk | 0:5e090fec6099 | 236 | } |