car using PID from centre line
Dependencies: FRDM-TFC mbed CBuffer XBEE mbed_angular_speed motor2 MMA8451Q
Fork of KL25Z_Camera_Test by
main.cpp@10:1bd0224093e4, 2016-11-16 (annotated)
- Committer:
- FatCookies
- Date:
- Wed Nov 16 16:31:46 2016 +0000
- Revision:
- 10:1bd0224093e4
- Parent:
- 9:aa2ce38dec6b
- Child:
- 11:53de69b1840b
added right motor "compensation"
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
maximusismax | 8:7c5e6b1e7aa5 | 1 | //Autonomous Car GDP controller |
maximusismax | 8:7c5e6b1e7aa5 | 2 | //Written by various group members |
maximusismax | 8:7c5e6b1e7aa5 | 3 | //Commented & cleaned up by Max/Adam |
maximusismax | 8:7c5e6b1e7aa5 | 4 | |
maximusismax | 8:7c5e6b1e7aa5 | 5 | //To-do |
maximusismax | 8:7c5e6b1e7aa5 | 6 | // -Change xbee transmission to non-blocking |
maximusismax | 8:7c5e6b1e7aa5 | 7 | // -Improve start/stop detection and resultant action (setting PID values?) |
maximusismax | 8:7c5e6b1e7aa5 | 8 | |
maximusismax | 8:7c5e6b1e7aa5 | 9 | #include <stdarg.h> |
maximusismax | 8:7c5e6b1e7aa5 | 10 | #include <stdio.h> |
maximusismax | 8:7c5e6b1e7aa5 | 11 | |
maximusismax | 0:566127ca8048 | 12 | #include "mbed.h" |
maximusismax | 0:566127ca8048 | 13 | #include "TFC.h" |
FatCookies | 4:4afa448c9cce | 14 | #include "XBEE.h" |
FatCookies | 9:aa2ce38dec6b | 15 | #include "angular_speed.h" |
maximusismax | 8:7c5e6b1e7aa5 | 16 | |
maximusismax | 8:7c5e6b1e7aa5 | 17 | #define BAUD_RATE 57600 |
FatCookies | 6:b0e160c51013 | 18 | #define CAM_THRESHOLD 109 |
maximusismax | 8:7c5e6b1e7aa5 | 19 | #define CAM_DIFF 10 |
maximusismax | 8:7c5e6b1e7aa5 | 20 | |
FatCookies | 10:1bd0224093e4 | 21 | #define RIGHT_MOTOR_COMPENSATION_RATIO 1.1586276 |
FatCookies | 10:1bd0224093e4 | 22 | |
FatCookies | 3:87a5122682fa | 23 | //Serial pc(USBTX,USBRX); |
FatCookies | 3:87a5122682fa | 24 | Serial pc(PTD3,PTD2); |
FatCookies | 4:4afa448c9cce | 25 | XBEE xb(&pc); |
FatCookies | 3:87a5122682fa | 26 | |
maximusismax | 8:7c5e6b1e7aa5 | 27 | //Woo global variables! |
maximusismax | 8:7c5e6b1e7aa5 | 28 | bool onTrack; |
FatCookies | 3:87a5122682fa | 29 | char curr_line[128]; |
FatCookies | 3:87a5122682fa | 30 | uint8_t curr_left; |
FatCookies | 3:87a5122682fa | 31 | uint8_t curr_right; |
FatCookies | 3:87a5122682fa | 32 | uint8_t right; |
FatCookies | 3:87a5122682fa | 33 | uint8_t left; |
maximusismax | 8:7c5e6b1e7aa5 | 34 | int8_t leftChange; |
maximusismax | 8:7c5e6b1e7aa5 | 35 | int8_t rightChange; |
maximusismax | 8:7c5e6b1e7aa5 | 36 | int diff; |
maximusismax | 8:7c5e6b1e7aa5 | 37 | int prev; |
maximusismax | 8:7c5e6b1e7aa5 | 38 | int i = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 39 | float measuredValBuffer[5]; |
maximusismax | 8:7c5e6b1e7aa5 | 40 | uint8_t valBufferIndex; |
maximusismax | 8:7c5e6b1e7aa5 | 41 | |
maximusismax | 8:7c5e6b1e7aa5 | 42 | //Some PID variables |
maximusismax | 8:7c5e6b1e7aa5 | 43 | float Kp; |
maximusismax | 8:7c5e6b1e7aa5 | 44 | float Ki; |
maximusismax | 8:7c5e6b1e7aa5 | 45 | float Kd; |
maximusismax | 8:7c5e6b1e7aa5 | 46 | float dt; |
maximusismax | 8:7c5e6b1e7aa5 | 47 | float p_error; |
maximusismax | 8:7c5e6b1e7aa5 | 48 | float pid_error; |
maximusismax | 8:7c5e6b1e7aa5 | 49 | float integral; |
maximusismax | 8:7c5e6b1e7aa5 | 50 | float measured_value, desired_value, derivative; |
maximusismax | 8:7c5e6b1e7aa5 | 51 | float output; |
FatCookies | 3:87a5122682fa | 52 | Timer t; |
FatCookies | 4:4afa448c9cce | 53 | |
FatCookies | 9:aa2ce38dec6b | 54 | //Speed Sensors variables |
FatCookies | 9:aa2ce38dec6b | 55 | InterruptIn leftHallSensor(D0); |
FatCookies | 9:aa2ce38dec6b | 56 | InterruptIn rightHallSensor(D2); |
FatCookies | 9:aa2ce38dec6b | 57 | Timer t1; |
FatCookies | 9:aa2ce38dec6b | 58 | Timer t2; |
FatCookies | 9:aa2ce38dec6b | 59 | volatile float Time_L,Time_R; |
FatCookies | 9:aa2ce38dec6b | 60 | float wL, wR; |
FatCookies | 9:aa2ce38dec6b | 61 | void GetTime_L(); |
FatCookies | 9:aa2ce38dec6b | 62 | void GetTime_R(); |
FatCookies | 9:aa2ce38dec6b | 63 | inline void initSpeedSensors(); |
FatCookies | 9:aa2ce38dec6b | 64 | |
FatCookies | 9:aa2ce38dec6b | 65 | // Current comms command |
FatCookies | 4:4afa448c9cce | 66 | char curr_cmd = 0; |
FatCookies | 4:4afa448c9cce | 67 | |
FatCookies | 4:4afa448c9cce | 68 | float speed = 0.3; |
FatCookies | 6:b0e160c51013 | 69 | int frame_counter = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 70 | |
maximusismax | 8:7c5e6b1e7aa5 | 71 | //Hacky start/stop signal detection |
maximusismax | 8:7c5e6b1e7aa5 | 72 | int startstop = 0; |
FatCookies | 7:ad893fc41b95 | 73 | bool seen = false; |
maximusismax | 8:7c5e6b1e7aa5 | 74 | |
maximusismax | 8:7c5e6b1e7aa5 | 75 | void sendString(const char *format, ...); |
maximusismax | 8:7c5e6b1e7aa5 | 76 | void initVariables(); |
maximusismax | 8:7c5e6b1e7aa5 | 77 | inline void handleComms(); |
maximusismax | 8:7c5e6b1e7aa5 | 78 | inline float findCentreValue(); |
maximusismax | 8:7c5e6b1e7aa5 | 79 | inline void PIDController(); |
maximusismax | 8:7c5e6b1e7aa5 | 80 | inline void sendImage(); |
maximusismax | 8:7c5e6b1e7aa5 | 81 | |
maximusismax | 0:566127ca8048 | 82 | int main() { |
maximusismax | 8:7c5e6b1e7aa5 | 83 | //Set up TFC driver stuff |
maximusismax | 0:566127ca8048 | 84 | TFC_Init(); |
FatCookies | 3:87a5122682fa | 85 | TFC_InitServos(0.00052,0.00122,0.02); |
maximusismax | 8:7c5e6b1e7aa5 | 86 | //Old things to make the car move at run-time |
maximusismax | 8:7c5e6b1e7aa5 | 87 | //Should tie these to a button for the actual races |
FatCookies | 4:4afa448c9cce | 88 | //TFC_HBRIDGE_ENABLE; |
FatCookies | 4:4afa448c9cce | 89 | //TFC_SetMotorPWM(0.3,0.3); |
maximusismax | 2:4b6f6fc84793 | 90 | |
maximusismax | 8:7c5e6b1e7aa5 | 91 | //Setup baud rate for serial link, do not change! |
maximusismax | 8:7c5e6b1e7aa5 | 92 | pc.baud(BAUD_RATE); |
maximusismax | 0:566127ca8048 | 93 | |
maximusismax | 8:7c5e6b1e7aa5 | 94 | //Initialise/reset PID variables |
maximusismax | 8:7c5e6b1e7aa5 | 95 | initVariables(); |
FatCookies | 9:aa2ce38dec6b | 96 | initSpeedSensors(); |
maximusismax | 0:566127ca8048 | 97 | |
maximusismax | 0:566127ca8048 | 98 | while(1) { |
FatCookies | 3:87a5122682fa | 99 | |
maximusismax | 8:7c5e6b1e7aa5 | 100 | handleComms(); |
maximusismax | 8:7c5e6b1e7aa5 | 101 | |
maximusismax | 8:7c5e6b1e7aa5 | 102 | //If we have an image ready |
maximusismax | 8:7c5e6b1e7aa5 | 103 | if(TFC_LineScanImageReady>0) { |
maximusismax | 8:7c5e6b1e7aa5 | 104 | measured_value = findCentreValue(); |
maximusismax | 8:7c5e6b1e7aa5 | 105 | |
maximusismax | 8:7c5e6b1e7aa5 | 106 | PIDController(); |
maximusismax | 8:7c5e6b1e7aa5 | 107 | |
maximusismax | 8:7c5e6b1e7aa5 | 108 | sendImage(); |
maximusismax | 8:7c5e6b1e7aa5 | 109 | |
maximusismax | 8:7c5e6b1e7aa5 | 110 | //Hacky way to detect the start/stop signal |
maximusismax | 8:7c5e6b1e7aa5 | 111 | if(right - left < 60) { |
maximusismax | 8:7c5e6b1e7aa5 | 112 | pc.putc('E'); |
maximusismax | 8:7c5e6b1e7aa5 | 113 | pc.printf("START STOP!! &d",startstop); |
maximusismax | 8:7c5e6b1e7aa5 | 114 | pc.putc(0); |
maximusismax | 8:7c5e6b1e7aa5 | 115 | |
maximusismax | 8:7c5e6b1e7aa5 | 116 | if(seen) { |
maximusismax | 8:7c5e6b1e7aa5 | 117 | seen = false; |
maximusismax | 8:7c5e6b1e7aa5 | 118 | } else { |
maximusismax | 8:7c5e6b1e7aa5 | 119 | startstop++; |
maximusismax | 8:7c5e6b1e7aa5 | 120 | seen = true; |
maximusismax | 8:7c5e6b1e7aa5 | 121 | } |
maximusismax | 8:7c5e6b1e7aa5 | 122 | //If we've done 5 laps, stop the car |
maximusismax | 8:7c5e6b1e7aa5 | 123 | if(startstop >= 1) { |
maximusismax | 8:7c5e6b1e7aa5 | 124 | TFC_SetMotorPWM(0.0,0.0); |
maximusismax | 8:7c5e6b1e7aa5 | 125 | TFC_HBRIDGE_DISABLE; |
maximusismax | 8:7c5e6b1e7aa5 | 126 | startstop = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 127 | } |
maximusismax | 8:7c5e6b1e7aa5 | 128 | } |
maximusismax | 8:7c5e6b1e7aa5 | 129 | |
maximusismax | 8:7c5e6b1e7aa5 | 130 | //Reset image ready flag |
maximusismax | 8:7c5e6b1e7aa5 | 131 | TFC_LineScanImageReady=0; |
maximusismax | 8:7c5e6b1e7aa5 | 132 | } |
maximusismax | 8:7c5e6b1e7aa5 | 133 | } |
maximusismax | 8:7c5e6b1e7aa5 | 134 | } |
maximusismax | 8:7c5e6b1e7aa5 | 135 | |
maximusismax | 8:7c5e6b1e7aa5 | 136 | void sendString(const char *format, ...) { |
maximusismax | 8:7c5e6b1e7aa5 | 137 | va_list arg; |
maximusismax | 8:7c5e6b1e7aa5 | 138 | |
maximusismax | 8:7c5e6b1e7aa5 | 139 | pc.putc('E'); |
maximusismax | 8:7c5e6b1e7aa5 | 140 | va_start (arg, format); |
maximusismax | 8:7c5e6b1e7aa5 | 141 | pc.vprintf(format,arg); |
maximusismax | 8:7c5e6b1e7aa5 | 142 | va_end (arg); |
maximusismax | 8:7c5e6b1e7aa5 | 143 | pc.putc(0); |
maximusismax | 8:7c5e6b1e7aa5 | 144 | } |
maximusismax | 8:7c5e6b1e7aa5 | 145 | |
maximusismax | 8:7c5e6b1e7aa5 | 146 | void initVariables() { |
maximusismax | 8:7c5e6b1e7aa5 | 147 | //Tunable PID variables |
maximusismax | 8:7c5e6b1e7aa5 | 148 | Kp = 125 / 25.0f; |
maximusismax | 8:7c5e6b1e7aa5 | 149 | Ki = 12.0f / 25.0f; |
maximusismax | 8:7c5e6b1e7aa5 | 150 | Kd = 0.0f; |
maximusismax | 8:7c5e6b1e7aa5 | 151 | dt = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 152 | p_error = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 153 | pid_error = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 154 | integral = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 155 | measured_value = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 156 | desired_value = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 157 | derivative = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 158 | |
maximusismax | 8:7c5e6b1e7aa5 | 159 | valBufferIndex = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 160 | //Measured value is a float between -1.0 and 1.0 (from left to right) |
maximusismax | 8:7c5e6b1e7aa5 | 161 | //Desired value is always 0.0 (as in, car is in the middle of the road) |
maximusismax | 8:7c5e6b1e7aa5 | 162 | } |
maximusismax | 8:7c5e6b1e7aa5 | 163 | |
maximusismax | 8:7c5e6b1e7aa5 | 164 | inline void sendImage() { |
maximusismax | 8:7c5e6b1e7aa5 | 165 | //Only send 1/3 of camera frames to GUI program |
maximusismax | 8:7c5e6b1e7aa5 | 166 | if((frame_counter % 3) == 0) { |
maximusismax | 8:7c5e6b1e7aa5 | 167 | pc.putc('H'); |
maximusismax | 8:7c5e6b1e7aa5 | 168 | for(i = 0; i < 128; i++) { |
maximusismax | 8:7c5e6b1e7aa5 | 169 | pc.putc((int8_t)(TFC_LineScanImage0[i] >> 4) & 0xFF); |
maximusismax | 8:7c5e6b1e7aa5 | 170 | } |
FatCookies | 9:aa2ce38dec6b | 171 | |
FatCookies | 9:aa2ce38dec6b | 172 | wL=Get_Speed(Time_L); |
FatCookies | 9:aa2ce38dec6b | 173 | wR=Get_Speed(Time_R); |
FatCookies | 9:aa2ce38dec6b | 174 | sendString("wL = %f, wR = %f",wL,wR); |
maximusismax | 8:7c5e6b1e7aa5 | 175 | } |
maximusismax | 8:7c5e6b1e7aa5 | 176 | frame_counter++; |
maximusismax | 8:7c5e6b1e7aa5 | 177 | } |
maximusismax | 8:7c5e6b1e7aa5 | 178 | |
maximusismax | 8:7c5e6b1e7aa5 | 179 | inline void handleComms() { |
maximusismax | 8:7c5e6b1e7aa5 | 180 | if(curr_cmd != 0) { |
FatCookies | 4:4afa448c9cce | 181 | switch(curr_cmd) { |
FatCookies | 4:4afa448c9cce | 182 | case 'A': |
FatCookies | 4:4afa448c9cce | 183 | if(xb.cBuffer->available() >= 3) { |
FatCookies | 4:4afa448c9cce | 184 | char p = xb.cBuffer->read(); |
FatCookies | 4:4afa448c9cce | 185 | char i = xb.cBuffer->read(); |
FatCookies | 4:4afa448c9cce | 186 | char d = xb.cBuffer->read(); |
FatCookies | 6:b0e160c51013 | 187 | Kp = p/25.0f; |
FatCookies | 6:b0e160c51013 | 188 | Ki = i/25.0f; |
FatCookies | 6:b0e160c51013 | 189 | Kd = d/25.0f; |
FatCookies | 4:4afa448c9cce | 190 | pc.putc('E'); |
maximusismax | 8:7c5e6b1e7aa5 | 191 | pc.printf("pid change, Kp: %f, Ki: %f, Kd: %f, p: %u, i: %u, d: %u", Kp, Ki, Kd, p, i, d); |
FatCookies | 6:b0e160c51013 | 192 | pc.putc(0); |
maximusismax | 8:7c5e6b1e7aa5 | 193 | |
FatCookies | 4:4afa448c9cce | 194 | curr_cmd = 0; |
FatCookies | 4:4afa448c9cce | 195 | } |
FatCookies | 4:4afa448c9cce | 196 | break; |
FatCookies | 4:4afa448c9cce | 197 | |
FatCookies | 4:4afa448c9cce | 198 | case 'F': |
FatCookies | 6:b0e160c51013 | 199 | if(xb.cBuffer->available() >= 1) { |
FatCookies | 4:4afa448c9cce | 200 | char a = xb.cBuffer->read(); |
FatCookies | 6:b0e160c51013 | 201 | speed = a/256.0f; |
FatCookies | 7:ad893fc41b95 | 202 | TFC_SetMotorPWM(speed,speed); |
FatCookies | 4:4afa448c9cce | 203 | pc.putc('E'); |
FatCookies | 6:b0e160c51013 | 204 | pc.printf("s = %u %f",a, speed); |
FatCookies | 6:b0e160c51013 | 205 | pc.putc(0); |
FatCookies | 4:4afa448c9cce | 206 | curr_cmd = 0; |
FatCookies | 4:4afa448c9cce | 207 | |
FatCookies | 4:4afa448c9cce | 208 | } |
FatCookies | 4:4afa448c9cce | 209 | break; |
FatCookies | 4:4afa448c9cce | 210 | |
FatCookies | 4:4afa448c9cce | 211 | default: |
FatCookies | 4:4afa448c9cce | 212 | break; |
FatCookies | 4:4afa448c9cce | 213 | } |
FatCookies | 4:4afa448c9cce | 214 | } |
FatCookies | 4:4afa448c9cce | 215 | |
FatCookies | 6:b0e160c51013 | 216 | if(xb.cBuffer->available() > 0 && curr_cmd == 0) { |
FatCookies | 4:4afa448c9cce | 217 | char cmd = xb.cBuffer->read(); |
FatCookies | 4:4afa448c9cce | 218 | if(cmd == 'D') { |
FatCookies | 4:4afa448c9cce | 219 | TFC_InitServos(0.00052,0.00122,0.02); |
FatCookies | 4:4afa448c9cce | 220 | TFC_HBRIDGE_ENABLE; |
FatCookies | 10:1bd0224093e4 | 221 | TFC_SetMotorPWM(RIGHT_MOTOR_COMPENSATION_RATIO*speed,speed); |
FatCookies | 6:b0e160c51013 | 222 | integral = 0; |
FatCookies | 6:b0e160c51013 | 223 | |
FatCookies | 4:4afa448c9cce | 224 | } else if (cmd == 'C') { |
FatCookies | 4:4afa448c9cce | 225 | TFC_SetMotorPWM(0.0,0.0); |
FatCookies | 4:4afa448c9cce | 226 | TFC_HBRIDGE_DISABLE; |
FatCookies | 4:4afa448c9cce | 227 | } else if(cmd == 'A') { |
FatCookies | 4:4afa448c9cce | 228 | curr_cmd = 'A'; |
FatCookies | 4:4afa448c9cce | 229 | } else if(cmd == 'F') { |
FatCookies | 4:4afa448c9cce | 230 | curr_cmd = 'F'; |
FatCookies | 4:4afa448c9cce | 231 | } |
FatCookies | 4:4afa448c9cce | 232 | |
FatCookies | 4:4afa448c9cce | 233 | } |
maximusismax | 8:7c5e6b1e7aa5 | 234 | } |
maximusismax | 8:7c5e6b1e7aa5 | 235 | inline float findCentreValue() { |
maximusismax | 8:7c5e6b1e7aa5 | 236 | float measuredValue; |
maximusismax | 8:7c5e6b1e7aa5 | 237 | |
maximusismax | 8:7c5e6b1e7aa5 | 238 | diff = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 239 | prev = -1; |
maximusismax | 8:7c5e6b1e7aa5 | 240 | leftChange = left; |
maximusismax | 8:7c5e6b1e7aa5 | 241 | for(i = 63; i > 0; i--) { |
maximusismax | 8:7c5e6b1e7aa5 | 242 | curr_left = (int8_t)(TFC_LineScanImage0[i] >> 4) & 0xFF; |
maximusismax | 8:7c5e6b1e7aa5 | 243 | diff = prev - curr_left; |
maximusismax | 8:7c5e6b1e7aa5 | 244 | if(abs(diff) >= 10 && curr_left <= 100 && prev != -1) { |
maximusismax | 8:7c5e6b1e7aa5 | 245 | left = i; |
maximusismax | 8:7c5e6b1e7aa5 | 246 | break; |
maximusismax | 8:7c5e6b1e7aa5 | 247 | } |
maximusismax | 8:7c5e6b1e7aa5 | 248 | prev = curr_left; |
maximusismax | 8:7c5e6b1e7aa5 | 249 | } |
maximusismax | 8:7c5e6b1e7aa5 | 250 | |
maximusismax | 8:7c5e6b1e7aa5 | 251 | prev = -1; |
maximusismax | 8:7c5e6b1e7aa5 | 252 | rightChange = right; |
maximusismax | 8:7c5e6b1e7aa5 | 253 | for(i = 64; i < 128; i++) { |
maximusismax | 8:7c5e6b1e7aa5 | 254 | curr_right = (int8_t)(TFC_LineScanImage0[i] >> 4) & 0xFF; |
maximusismax | 8:7c5e6b1e7aa5 | 255 | int diff = prev - curr_right; |
maximusismax | 8:7c5e6b1e7aa5 | 256 | if(abs(diff) >= 10 && curr_right <= 100 && prev != -1) { |
maximusismax | 8:7c5e6b1e7aa5 | 257 | right = i; |
maximusismax | 8:7c5e6b1e7aa5 | 258 | break; |
maximusismax | 8:7c5e6b1e7aa5 | 259 | } |
maximusismax | 8:7c5e6b1e7aa5 | 260 | prev = curr_right; |
maximusismax | 8:7c5e6b1e7aa5 | 261 | } |
maximusismax | 8:7c5e6b1e7aa5 | 262 | |
maximusismax | 8:7c5e6b1e7aa5 | 263 | //Calculate how left/right we are |
maximusismax | 8:7c5e6b1e7aa5 | 264 | measuredValue = (64 - ((left+right)/2))/64.f; |
maximusismax | 8:7c5e6b1e7aa5 | 265 | measuredValBuffer[valBufferIndex % 5] = measuredValue; |
maximusismax | 8:7c5e6b1e7aa5 | 266 | valBufferIndex++; |
maximusismax | 8:7c5e6b1e7aa5 | 267 | |
maximusismax | 8:7c5e6b1e7aa5 | 268 | return measuredValue; |
maximusismax | 8:7c5e6b1e7aa5 | 269 | } |
FatCookies | 3:87a5122682fa | 270 | |
maximusismax | 8:7c5e6b1e7aa5 | 271 | inline void PIDController() { |
maximusismax | 8:7c5e6b1e7aa5 | 272 | //PID Stuff! |
FatCookies | 3:87a5122682fa | 273 | t.start(); |
maximusismax | 8:7c5e6b1e7aa5 | 274 | dt = t.read(); |
maximusismax | 8:7c5e6b1e7aa5 | 275 | pid_error = desired_value - measured_value; |
maximusismax | 8:7c5e6b1e7aa5 | 276 | integral = integral + pid_error * dt; |
maximusismax | 8:7c5e6b1e7aa5 | 277 | derivative = (pid_error - p_error) / dt; |
maximusismax | 8:7c5e6b1e7aa5 | 278 | output = Kp * pid_error + Ki * integral + Kd * derivative; |
maximusismax | 8:7c5e6b1e7aa5 | 279 | p_error = pid_error; |
maximusismax | 8:7c5e6b1e7aa5 | 280 | |
maximusismax | 8:7c5e6b1e7aa5 | 281 | if(integral > 1.0f) { |
FatCookies | 6:b0e160c51013 | 282 | integral = 1.0f; |
FatCookies | 6:b0e160c51013 | 283 | } |
FatCookies | 6:b0e160c51013 | 284 | if(integral < -1.0f) { |
FatCookies | 6:b0e160c51013 | 285 | integral = -1.0f; |
FatCookies | 6:b0e160c51013 | 286 | } |
FatCookies | 6:b0e160c51013 | 287 | |
maximusismax | 8:7c5e6b1e7aa5 | 288 | if((-1.0 <= output) && (output <= 1.0)) |
FatCookies | 6:b0e160c51013 | 289 | { |
maximusismax | 8:7c5e6b1e7aa5 | 290 | TFC_SetServo(0, output); |
maximusismax | 8:7c5e6b1e7aa5 | 291 | } |
maximusismax | 8:7c5e6b1e7aa5 | 292 | else //Unhappy PID state |
maximusismax | 8:7c5e6b1e7aa5 | 293 | { |
maximusismax | 8:7c5e6b1e7aa5 | 294 | pc.putc('E'); |
maximusismax | 8:7c5e6b1e7aa5 | 295 | pc.printf("pid unhappy"); |
maximusismax | 8:7c5e6b1e7aa5 | 296 | pc.putc(0); |
maximusismax | 8:7c5e6b1e7aa5 | 297 | pc.putc('E'); |
maximusismax | 8:7c5e6b1e7aa5 | 298 | pc.printf("out = %f p_err = %f", output, p_error); |
maximusismax | 8:7c5e6b1e7aa5 | 299 | pc.putc(0); |
maximusismax | 8:7c5e6b1e7aa5 | 300 | TFC_InitServos(0.00052, 0.00122, 0.02); |
maximusismax | 8:7c5e6b1e7aa5 | 301 | //output, pid_error, p_error, integral, derivative = 0; |
maximusismax | 8:7c5e6b1e7aa5 | 302 | |
maximusismax | 8:7c5e6b1e7aa5 | 303 | if(output >= 1.0f) { |
maximusismax | 8:7c5e6b1e7aa5 | 304 | TFC_SetServo(0, 0.9f); |
maximusismax | 8:7c5e6b1e7aa5 | 305 | output = 1.0f; |
maximusismax | 8:7c5e6b1e7aa5 | 306 | } else { |
maximusismax | 8:7c5e6b1e7aa5 | 307 | TFC_SetServo(0, -0.9f); |
maximusismax | 8:7c5e6b1e7aa5 | 308 | output = -1.0f; |
maximusismax | 8:7c5e6b1e7aa5 | 309 | } |
maximusismax | 8:7c5e6b1e7aa5 | 310 | } |
FatCookies | 6:b0e160c51013 | 311 | |
FatCookies | 3:87a5122682fa | 312 | t.stop(); |
FatCookies | 3:87a5122682fa | 313 | t.reset(); |
FatCookies | 3:87a5122682fa | 314 | t.start(); |
FatCookies | 9:aa2ce38dec6b | 315 | } |
FatCookies | 9:aa2ce38dec6b | 316 | |
FatCookies | 9:aa2ce38dec6b | 317 | |
FatCookies | 9:aa2ce38dec6b | 318 | |
FatCookies | 9:aa2ce38dec6b | 319 | inline void initSpeedSensors() { |
FatCookies | 9:aa2ce38dec6b | 320 | t1.start(); |
FatCookies | 9:aa2ce38dec6b | 321 | t2.start(); |
FatCookies | 9:aa2ce38dec6b | 322 | |
FatCookies | 9:aa2ce38dec6b | 323 | //Left and Right are defined looking at the rear of the car, in the direction the camera points at. |
FatCookies | 9:aa2ce38dec6b | 324 | leftHallSensor.rise(&GetTime_L); |
FatCookies | 9:aa2ce38dec6b | 325 | rightHallSensor.rise(&GetTime_R); |
FatCookies | 9:aa2ce38dec6b | 326 | } |
FatCookies | 9:aa2ce38dec6b | 327 | |
FatCookies | 9:aa2ce38dec6b | 328 | void GetTime_L(){ |
FatCookies | 9:aa2ce38dec6b | 329 | Time_L=t1.read_us(); |
FatCookies | 9:aa2ce38dec6b | 330 | t1.reset(); |
FatCookies | 9:aa2ce38dec6b | 331 | } |
FatCookies | 9:aa2ce38dec6b | 332 | |
FatCookies | 9:aa2ce38dec6b | 333 | void GetTime_R(){ |
FatCookies | 9:aa2ce38dec6b | 334 | Time_R=t2.read_us(); |
FatCookies | 9:aa2ce38dec6b | 335 | t2.reset(); |
maximusismax | 0:566127ca8048 | 336 | } |