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