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@23:b234e8fb51b3, 2016-12-09 (annotated)
- Committer:
- lh14g13
- Date:
- Fri Dec 09 11:20:24 2016 +0000
- Revision:
- 23:b234e8fb51b3
- Parent:
- 19:65f0b6febc23
something changed
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" |
FatCookies | 14:13085e161dd1 | 16 | #include "main.h" |
FatCookies | 12:da96e2f87465 | 17 | #include "motor.h" |
maximusismax | 8:7c5e6b1e7aa5 | 18 | |
FatCookies | 17:6ae90788cc2b | 19 | // Serial |
FatCookies | 17:6ae90788cc2b | 20 | #if USE_COMMS |
FatCookies | 17:6ae90788cc2b | 21 | Serial pc(PTD3,PTD2); |
FatCookies | 17:6ae90788cc2b | 22 | XBEE xb(&pc); |
FatCookies | 17:6ae90788cc2b | 23 | #endif |
FatCookies | 3:87a5122682fa | 24 | |
FatCookies | 17:6ae90788cc2b | 25 | // PID Timer |
FatCookies | 3:87a5122682fa | 26 | Timer t; |
FatCookies | 4:4afa448c9cce | 27 | |
FatCookies | 17:6ae90788cc2b | 28 | //Speed Sensors interupts and timers |
FatCookies | 9:aa2ce38dec6b | 29 | InterruptIn leftHallSensor(D0); |
FatCookies | 9:aa2ce38dec6b | 30 | InterruptIn rightHallSensor(D2); |
FatCookies | 9:aa2ce38dec6b | 31 | Timer t1; |
FatCookies | 9:aa2ce38dec6b | 32 | Timer t2; |
FatCookies | 9:aa2ce38dec6b | 33 | |
lh14g13 | 18:0095a3a8f8e4 | 34 | //testing timer |
lh14g13 | 18:0095a3a8f8e4 | 35 | Timer test; |
FatCookies | 16:81cdffd8c5d5 | 36 | |
maximusismax | 0:566127ca8048 | 37 | int main() { |
maximusismax | 8:7c5e6b1e7aa5 | 38 | //Set up TFC driver stuff |
maximusismax | 0:566127ca8048 | 39 | TFC_Init(); |
FatCookies | 17:6ae90788cc2b | 40 | ALIGN_SERVO; |
FatCookies | 13:4e77264f254a | 41 | |
FatCookies | 17:6ae90788cc2b | 42 | #if USE_COMMS |
FatCookies | 17:6ae90788cc2b | 43 | //Setup baud rate for serial link, do not change! |
FatCookies | 17:6ae90788cc2b | 44 | pc.baud(BAUD_RATE); |
FatCookies | 17:6ae90788cc2b | 45 | #endif |
maximusismax | 0:566127ca8048 | 46 | |
maximusismax | 8:7c5e6b1e7aa5 | 47 | //Initialise/reset PID variables |
maximusismax | 8:7c5e6b1e7aa5 | 48 | initVariables(); |
FatCookies | 9:aa2ce38dec6b | 49 | initSpeedSensors(); |
FatCookies | 12:da96e2f87465 | 50 | |
FatCookies | 13:4e77264f254a | 51 | |
maximusismax | 0:566127ca8048 | 52 | while(1) { |
FatCookies | 3:87a5122682fa | 53 | |
FatCookies | 17:6ae90788cc2b | 54 | #if USE_COMMS |
FatCookies | 17:6ae90788cc2b | 55 | handleComms(); |
FatCookies | 17:6ae90788cc2b | 56 | #endif |
maximusismax | 8:7c5e6b1e7aa5 | 57 | |
maximusismax | 8:7c5e6b1e7aa5 | 58 | //If we have an image ready |
FatCookies | 13:4e77264f254a | 59 | if(TFC_LineScanImageReady>0) { |
FatCookies | 13:4e77264f254a | 60 | /* Find the bounds of the track and calculate how close we are to |
FatCookies | 13:4e77264f254a | 61 | * the centre */ |
FatCookies | 17:6ae90788cc2b | 62 | servo_pid.measured_value = findCentreValue(CLOSE_CAMERA, left, right); |
maximusismax | 8:7c5e6b1e7aa5 | 63 | |
lh14g13 | 19:65f0b6febc23 | 64 | |
FatCookies | 13:4e77264f254a | 65 | |
FatCookies | 17:6ae90788cc2b | 66 | // Slow down, adjust PID values and enable differential before corners. |
FatCookies | 17:6ae90788cc2b | 67 | handleCornering(); |
FatCookies | 17:6ae90788cc2b | 68 | |
FatCookies | 13:4e77264f254a | 69 | // Run the PID controllers and adjust steering/motor accordingly |
maximusismax | 8:7c5e6b1e7aa5 | 70 | PIDController(); |
maximusismax | 8:7c5e6b1e7aa5 | 71 | |
FatCookies | 17:6ae90788cc2b | 72 | #if USE_COMMS |
FatCookies | 17:6ae90788cc2b | 73 | // Send the line scan image over serial |
FatCookies | 17:6ae90788cc2b | 74 | sendImage(); |
FatCookies | 17:6ae90788cc2b | 75 | |
FatCookies | 17:6ae90788cc2b | 76 | // Send the wheel speeds over serial |
FatCookies | 17:6ae90788cc2b | 77 | sendSpeeds(); |
FatCookies | 17:6ae90788cc2b | 78 | #endif |
FatCookies | 13:4e77264f254a | 79 | |
FatCookies | 13:4e77264f254a | 80 | // Check if car is at the stop line |
lh14g13 | 19:65f0b6febc23 | 81 | //handleStartStop(); |
maximusismax | 8:7c5e6b1e7aa5 | 82 | |
FatCookies | 15:ccde02f96449 | 83 | |
maximusismax | 8:7c5e6b1e7aa5 | 84 | //Reset image ready flag |
maximusismax | 8:7c5e6b1e7aa5 | 85 | TFC_LineScanImageReady=0; |
maximusismax | 8:7c5e6b1e7aa5 | 86 | } |
maximusismax | 8:7c5e6b1e7aa5 | 87 | } |
maximusismax | 8:7c5e6b1e7aa5 | 88 | } |
maximusismax | 8:7c5e6b1e7aa5 | 89 | |
FatCookies | 17:6ae90788cc2b | 90 | void initVariables() { |
FatCookies | 17:6ae90788cc2b | 91 | // Initialise three PID controllers for the servo and each wheel. |
FatCookies | 17:6ae90788cc2b | 92 | initPID(&servo_pid, 2.2f, 0.6f, 0.f); |
lh14g13 | 19:65f0b6febc23 | 93 | initPID(&left_motor_pid, 0.01f, 0.f, 0.f); |
lh14g13 | 19:65f0b6febc23 | 94 | initPID(&right_motor_pid, 0.01f, 0.f, 0.f); |
FatCookies | 17:6ae90788cc2b | 95 | |
lh14g13 | 19:65f0b6febc23 | 96 | right_motor_pid.desired_value=0; |
lh14g13 | 19:65f0b6febc23 | 97 | left_motor_pid.desired_value=0; |
lh14g13 | 19:65f0b6febc23 | 98 | |
lh14g13 | 19:65f0b6febc23 | 99 | // intialise the maximum speed interms of the angular speed. |
FatCookies | 17:6ae90788cc2b | 100 | valBufferIndex = 0; |
lh14g13 | 19:65f0b6febc23 | 101 | speed = 50; |
FatCookies | 13:4e77264f254a | 102 | |
FatCookies | 17:6ae90788cc2b | 103 | //Start stop |
FatCookies | 17:6ae90788cc2b | 104 | startstop = 0; |
FatCookies | 17:6ae90788cc2b | 105 | seen = false; |
FatCookies | 17:6ae90788cc2b | 106 | |
FatCookies | 17:6ae90788cc2b | 107 | // Turning |
FatCookies | 17:6ae90788cc2b | 108 | turning = 0; |
FatCookies | 17:6ae90788cc2b | 109 | keepTurning = 0; |
FatCookies | 17:6ae90788cc2b | 110 | slow = false; |
lh14g13 | 19:65f0b6febc23 | 111 | |
maximusismax | 8:7c5e6b1e7aa5 | 112 | } |
maximusismax | 8:7c5e6b1e7aa5 | 113 | |
FatCookies | 13:4e77264f254a | 114 | void initPID(pid_instance* pid, float Kp, float Ki, float Kd) { |
FatCookies | 17:6ae90788cc2b | 115 | pid->Kp = Kp; |
FatCookies | 13:4e77264f254a | 116 | pid->Ki = Ki; |
FatCookies | 13:4e77264f254a | 117 | pid->Kd = Kd; |
FatCookies | 13:4e77264f254a | 118 | pid->dt = 0; |
FatCookies | 13:4e77264f254a | 119 | pid->p_error = 0; |
FatCookies | 13:4e77264f254a | 120 | pid->pid_error = 0; |
FatCookies | 13:4e77264f254a | 121 | pid->integral = 0; |
FatCookies | 13:4e77264f254a | 122 | pid->measured_value = 0; |
FatCookies | 13:4e77264f254a | 123 | pid->desired_value = 0; |
FatCookies | 13:4e77264f254a | 124 | pid->derivative = 0; |
FatCookies | 13:4e77264f254a | 125 | } |
FatCookies | 13:4e77264f254a | 126 | |
FatCookies | 17:6ae90788cc2b | 127 | inline float findCentreValue(volatile uint16_t * cam_data, uint8_t &l, uint8_t &r) { |
FatCookies | 17:6ae90788cc2b | 128 | |
FatCookies | 17:6ae90788cc2b | 129 | diff = 0; |
FatCookies | 17:6ae90788cc2b | 130 | prev = -1; |
FatCookies | 17:6ae90788cc2b | 131 | for(i = 63; i > 0; i--) { |
FatCookies | 17:6ae90788cc2b | 132 | curr_left = (int8_t)(cam_data[i] >> 4) & 0xFF; |
FatCookies | 17:6ae90788cc2b | 133 | diff = prev - curr_left; |
FatCookies | 17:6ae90788cc2b | 134 | if(abs(diff) >= CAM_DIFF && curr_left <= CAM_THRESHOLD && prev != -1) { |
FatCookies | 17:6ae90788cc2b | 135 | l = i; |
FatCookies | 17:6ae90788cc2b | 136 | break; |
FatCookies | 17:6ae90788cc2b | 137 | } |
FatCookies | 17:6ae90788cc2b | 138 | prev = curr_left; |
FatCookies | 17:6ae90788cc2b | 139 | } |
maximusismax | 8:7c5e6b1e7aa5 | 140 | |
FatCookies | 17:6ae90788cc2b | 141 | prev = -1; |
FatCookies | 17:6ae90788cc2b | 142 | for(i = 64; i < 128; i++) { |
FatCookies | 17:6ae90788cc2b | 143 | curr_right = (int8_t)(cam_data[i] >> 4) & 0xFF; |
FatCookies | 17:6ae90788cc2b | 144 | int diff = prev - curr_right; |
FatCookies | 17:6ae90788cc2b | 145 | if(abs(diff) >= CAM_DIFF && curr_right <= CAM_THRESHOLD && prev != -1) { |
FatCookies | 17:6ae90788cc2b | 146 | r = i; |
FatCookies | 17:6ae90788cc2b | 147 | break; |
FatCookies | 17:6ae90788cc2b | 148 | } |
FatCookies | 17:6ae90788cc2b | 149 | prev = curr_right; |
FatCookies | 17:6ae90788cc2b | 150 | } |
FatCookies | 17:6ae90788cc2b | 151 | |
FatCookies | 17:6ae90788cc2b | 152 | //Calculate how left/right we are |
FatCookies | 17:6ae90788cc2b | 153 | return (64 - ((l+r)/2))/64.f; |
FatCookies | 13:4e77264f254a | 154 | } |
FatCookies | 13:4e77264f254a | 155 | |
FatCookies | 17:6ae90788cc2b | 156 | inline void handleCornering() { |
FatCookies | 12:da96e2f87465 | 157 | |
FatCookies | 17:6ae90788cc2b | 158 | float lookaheadMeasuredValue = findCentreValue(LOOKAHEAD_CAMERA, farLeft, farRight); |
FatCookies | 15:ccde02f96449 | 159 | |
FatCookies | 13:4e77264f254a | 160 | measuredValBuffer[frame_counter % 64] = servo_pid.measured_value; |
FatCookies | 13:4e77264f254a | 161 | |
FatCookies | 13:4e77264f254a | 162 | int count = 0; |
FatCookies | 13:4e77264f254a | 163 | for(i = 0; i < 10; i++) { |
FatCookies | 13:4e77264f254a | 164 | float val = abs(measuredValBuffer[(frame_counter - i) % 64]); |
FatCookies | 13:4e77264f254a | 165 | if(val > 0.09) { |
FatCookies | 13:4e77264f254a | 166 | count++; |
FatCookies | 13:4e77264f254a | 167 | } |
FatCookies | 13:4e77264f254a | 168 | } |
FatCookies | 12:da96e2f87465 | 169 | |
FatCookies | 17:6ae90788cc2b | 170 | if(!turning && abs(lookaheadMeasuredValue) > 0.11f){ |
FatCookies | 15:ccde02f96449 | 171 | TFC_SetMotorPWM(0.4,0.4); |
FatCookies | 15:ccde02f96449 | 172 | } |
FatCookies | 15:ccde02f96449 | 173 | |
FatCookies | 14:13085e161dd1 | 174 | if(turning) { |
lh14g13 | 18:0095a3a8f8e4 | 175 | |
lh14g13 | 18:0095a3a8f8e4 | 176 | //default |
lh14g13 | 18:0095a3a8f8e4 | 177 | //TFC_SetMotorPWM(0.4,0.4); |
lh14g13 | 18:0095a3a8f8e4 | 178 | |
lh14g13 | 19:65f0b6febc23 | 179 | //dutyCycleCorner(speed,servo_pid.output); |
lh14g13 | 18:0095a3a8f8e4 | 180 | |
lh14g13 | 18:0095a3a8f8e4 | 181 | //may want to have just to set cornering speed at different if going to be slowing down for cornering. |
lh14g13 | 18:0095a3a8f8e4 | 182 | //dutyCycleCorner(float cornerspeed, servo_pid.output); |
lh14g13 | 18:0095a3a8f8e4 | 183 | //dutyCycleCorner(speed, servo_pid.output); |
lh14g13 | 18:0095a3a8f8e4 | 184 | |
lh14g13 | 23:b234e8fb51b3 | 185 | sensorCorner(left_motor_pid.desired_value, right_motor_pid.desired_value , servo_pid.output, speed); |
lh14g13 | 23:b234e8fb51b3 | 186 | // may need speed for corner speed if slowing down for corner. |
FatCookies | 14:13085e161dd1 | 187 | } |
FatCookies | 14:13085e161dd1 | 188 | |
FatCookies | 13:4e77264f254a | 189 | if(abs(servo_pid.measured_value) > 0.11f){ |
FatCookies | 15:ccde02f96449 | 190 | if(!turning) { |
FatCookies | 13:4e77264f254a | 191 | turning = 1; |
FatCookies | 13:4e77264f254a | 192 | } else { |
FatCookies | 13:4e77264f254a | 193 | turning++; |
FatCookies | 13:4e77264f254a | 194 | } |
FatCookies | 13:4e77264f254a | 195 | |
FatCookies | 13:4e77264f254a | 196 | } else { |
FatCookies | 13:4e77264f254a | 197 | if(turning) { |
FatCookies | 13:4e77264f254a | 198 | if(keepTurning == 0 || count > 6) { |
FatCookies | 13:4e77264f254a | 199 | keepTurning++; |
FatCookies | 13:4e77264f254a | 200 | } else { |
FatCookies | 15:ccde02f96449 | 201 | //sendString("stop turning turned=%d",turning); |
FatCookies | 13:4e77264f254a | 202 | keepTurning = 0; |
lh14g13 | 23:b234e8fb51b3 | 203 | turning = 0; |
lh14g13 | 23:b234e8fb51b3 | 204 | |
lh14g13 | 23:b234e8fb51b3 | 205 | left_motor_pid.desired_value = speed; |
lh14g13 | 23:b234e8fb51b3 | 206 | right_motor_pid.desired_value = speed; |
lh14g13 | 23:b234e8fb51b3 | 207 | //TFC_SetMotorPWM(speed,speed); |
FatCookies | 13:4e77264f254a | 208 | } |
FatCookies | 13:4e77264f254a | 209 | |
FatCookies | 13:4e77264f254a | 210 | } |
FatCookies | 13:4e77264f254a | 211 | } |
FatCookies | 13:4e77264f254a | 212 | |
maximusismax | 8:7c5e6b1e7aa5 | 213 | } |
maximusismax | 8:7c5e6b1e7aa5 | 214 | |
FatCookies | 17:6ae90788cc2b | 215 | inline float getLineEntropy() { |
FatCookies | 17:6ae90788cc2b | 216 | float entropy = 0; |
FatCookies | 17:6ae90788cc2b | 217 | float last = (int8_t)(CLOSE_CAMERA[0] >> 4) & 0xFF; |
FatCookies | 17:6ae90788cc2b | 218 | for(int i = 1; i < 128; i++) { |
FatCookies | 17:6ae90788cc2b | 219 | entropy += abs(last - ((int8_t)(CLOSE_CAMERA[i] >> 4) & 0xFF)); |
FatCookies | 17:6ae90788cc2b | 220 | } |
FatCookies | 17:6ae90788cc2b | 221 | return entropy; |
FatCookies | 17:6ae90788cc2b | 222 | } |
FatCookies | 17:6ae90788cc2b | 223 | |
FatCookies | 17:6ae90788cc2b | 224 | void handlePID(pid_instance *pid) { |
FatCookies | 17:6ae90788cc2b | 225 | pid->dt = t.read(); |
FatCookies | 17:6ae90788cc2b | 226 | pid->pid_error = pid->desired_value - pid->measured_value; |
FatCookies | 17:6ae90788cc2b | 227 | pid->integral = pid->integral + pid->pid_error * pid->dt; |
FatCookies | 17:6ae90788cc2b | 228 | pid->derivative = (pid->pid_error - pid->p_error) / pid->dt; |
FatCookies | 17:6ae90788cc2b | 229 | pid->output = pid->Kp * pid->pid_error + pid->Ki * pid->integral + pid->Kd * pid->derivative; |
FatCookies | 17:6ae90788cc2b | 230 | pid->p_error = pid->pid_error; |
FatCookies | 17:6ae90788cc2b | 231 | |
FatCookies | 17:6ae90788cc2b | 232 | if(pid->integral > 1.0f) { |
FatCookies | 17:6ae90788cc2b | 233 | pid->integral = 1.0f; |
FatCookies | 17:6ae90788cc2b | 234 | } |
FatCookies | 17:6ae90788cc2b | 235 | if(pid->integral < -1.0f) { |
FatCookies | 17:6ae90788cc2b | 236 | pid->integral = -1.0f; |
FatCookies | 17:6ae90788cc2b | 237 | } |
FatCookies | 17:6ae90788cc2b | 238 | } |
FatCookies | 17:6ae90788cc2b | 239 | |
lh14g13 | 19:65f0b6febc23 | 240 | |
lh14g13 | 19:65f0b6febc23 | 241 | |
FatCookies | 17:6ae90788cc2b | 242 | inline void PIDController() { |
FatCookies | 17:6ae90788cc2b | 243 | // update motor measurements |
lh14g13 | 19:65f0b6febc23 | 244 | // Read the angular velocity of both wheels |
lh14g13 | 19:65f0b6febc23 | 245 | wL=Get_Speed(Time_L); |
lh14g13 | 19:65f0b6febc23 | 246 | wR=Get_Speed(Time_R); |
FatCookies | 17:6ae90788cc2b | 247 | left_motor_pid.measured_value = wL; |
FatCookies | 17:6ae90788cc2b | 248 | right_motor_pid.measured_value = wR; |
FatCookies | 17:6ae90788cc2b | 249 | |
FatCookies | 17:6ae90788cc2b | 250 | //PID Stuff! |
FatCookies | 17:6ae90788cc2b | 251 | t.start(); |
FatCookies | 17:6ae90788cc2b | 252 | handlePID(&servo_pid); |
FatCookies | 17:6ae90788cc2b | 253 | handlePID(&left_motor_pid); |
FatCookies | 17:6ae90788cc2b | 254 | handlePID(&right_motor_pid); |
FatCookies | 17:6ae90788cc2b | 255 | |
FatCookies | 17:6ae90788cc2b | 256 | if((-1.0 <= servo_pid.output) && (servo_pid.output <= 1.0)) |
FatCookies | 17:6ae90788cc2b | 257 | { |
FatCookies | 17:6ae90788cc2b | 258 | TFC_SetServo(0, servo_pid.output); |
FatCookies | 17:6ae90788cc2b | 259 | } |
FatCookies | 17:6ae90788cc2b | 260 | else //Unhappy PID state |
FatCookies | 17:6ae90788cc2b | 261 | { |
FatCookies | 17:6ae90788cc2b | 262 | //sendString("out = %f p_err = %f", servo_pid.output, servo_pid.p_error); |
FatCookies | 17:6ae90788cc2b | 263 | ALIGN_SERVO; |
FatCookies | 17:6ae90788cc2b | 264 | if(servo_pid.output >= 1.0f) { |
FatCookies | 17:6ae90788cc2b | 265 | TFC_SetServo(0, 0.9f); |
FatCookies | 17:6ae90788cc2b | 266 | servo_pid.output = 1.0f; |
FatCookies | 17:6ae90788cc2b | 267 | } else { |
FatCookies | 17:6ae90788cc2b | 268 | TFC_SetServo(0, -0.9f); |
FatCookies | 17:6ae90788cc2b | 269 | servo_pid.output = -1.0f; |
FatCookies | 17:6ae90788cc2b | 270 | } |
FatCookies | 17:6ae90788cc2b | 271 | } |
FatCookies | 17:6ae90788cc2b | 272 | |
FatCookies | 17:6ae90788cc2b | 273 | |
lh14g13 | 19:65f0b6febc23 | 274 | // need to get thepid to set the duty cycle |
lh14g13 | 19:65f0b6febc23 | 275 | // need to have the desired value set0 |
lh14g13 | 19:65f0b6febc23 | 276 | //MOTORS |
lh14g13 | 19:65f0b6febc23 | 277 | if((0<=left_motor_pid.output)&&(0<=right_motor_pid.output)) |
lh14g13 | 19:65f0b6febc23 | 278 | { |
lh14g13 | 19:65f0b6febc23 | 279 | TFC_SetMotorPWM(left_motor_pid.output,right_motor_pid.output); |
lh14g13 | 19:65f0b6febc23 | 280 | |
lh14g13 | 19:65f0b6febc23 | 281 | } |
lh14g13 | 19:65f0b6febc23 | 282 | else |
lh14g13 | 19:65f0b6febc23 | 283 | { |
lh14g13 | 19:65f0b6febc23 | 284 | if(0 > right_motor_pid.output) |
lh14g13 | 19:65f0b6febc23 | 285 | { |
lh14g13 | 23:b234e8fb51b3 | 286 | left_motor_pid.output=0; |
lh14g13 | 23:b234e8fb51b3 | 287 | |
lh14g13 | 19:65f0b6febc23 | 288 | } |
lh14g13 | 19:65f0b6febc23 | 289 | if(0 > left_motor_pid.output) |
lh14g13 | 19:65f0b6febc23 | 290 | { |
lh14g13 | 23:b234e8fb51b3 | 291 | right_motor_pid.output=0; |
lh14g13 | 23:b234e8fb51b3 | 292 | |
lh14g13 | 19:65f0b6febc23 | 293 | } |
lh14g13 | 23:b234e8fb51b3 | 294 | |
lh14g13 | 23:b234e8fb51b3 | 295 | TFC_SetMotorPWM(left_motor_pid.output,right_motor_pid.output); |
lh14g13 | 19:65f0b6febc23 | 296 | } |
lh14g13 | 19:65f0b6febc23 | 297 | |
lh14g13 | 19:65f0b6febc23 | 298 | |
lh14g13 | 19:65f0b6febc23 | 299 | |
lh14g13 | 19:65f0b6febc23 | 300 | |
lh14g13 | 19:65f0b6febc23 | 301 | |
lh14g13 | 19:65f0b6febc23 | 302 | |
lh14g13 | 19:65f0b6febc23 | 303 | |
FatCookies | 17:6ae90788cc2b | 304 | t.stop(); |
FatCookies | 17:6ae90788cc2b | 305 | t.reset(); |
FatCookies | 17:6ae90788cc2b | 306 | t.start(); |
FatCookies | 17:6ae90788cc2b | 307 | } |
FatCookies | 17:6ae90788cc2b | 308 | |
FatCookies | 17:6ae90788cc2b | 309 | inline void handleStartStop() { |
FatCookies | 17:6ae90788cc2b | 310 | //Hacky way to detect the start/stop signal |
FatCookies | 17:6ae90788cc2b | 311 | if(right - left < 60) { |
lh14g13 | 18:0095a3a8f8e4 | 312 | sendString("START STOP!! &d",startstop);//do you mean %d? |
lh14g13 | 18:0095a3a8f8e4 | 313 | |
lh14g13 | 18:0095a3a8f8e4 | 314 | lapTime(); |
lh14g13 | 18:0095a3a8f8e4 | 315 | //testSpeed(speed) HOLY SHIT ITS DAT BOI!!!!!!!! |
FatCookies | 17:6ae90788cc2b | 316 | if(seen) { |
FatCookies | 17:6ae90788cc2b | 317 | seen = false; |
FatCookies | 17:6ae90788cc2b | 318 | } else { |
FatCookies | 17:6ae90788cc2b | 319 | startstop++; |
FatCookies | 17:6ae90788cc2b | 320 | seen = true; |
FatCookies | 17:6ae90788cc2b | 321 | } |
FatCookies | 17:6ae90788cc2b | 322 | //If we've done 5 laps, stop the car |
FatCookies | 17:6ae90788cc2b | 323 | if(startstop >= 1) { |
FatCookies | 17:6ae90788cc2b | 324 | TFC_SetMotorPWM(0.f,0.f); |
FatCookies | 17:6ae90788cc2b | 325 | TFC_HBRIDGE_DISABLE; |
FatCookies | 17:6ae90788cc2b | 326 | startstop = 0; |
FatCookies | 17:6ae90788cc2b | 327 | } |
lh14g13 | 18:0095a3a8f8e4 | 328 | } |
lh14g13 | 18:0095a3a8f8e4 | 329 | |
FatCookies | 17:6ae90788cc2b | 330 | } |
FatCookies | 17:6ae90788cc2b | 331 | |
FatCookies | 17:6ae90788cc2b | 332 | |
FatCookies | 17:6ae90788cc2b | 333 | inline void initSpeedSensors() { |
FatCookies | 17:6ae90788cc2b | 334 | t1.start(); |
FatCookies | 17:6ae90788cc2b | 335 | t2.start(); |
FatCookies | 17:6ae90788cc2b | 336 | |
FatCookies | 17:6ae90788cc2b | 337 | //Left and Right are defined looking at the rear of the car, in the direction the camera points at. |
FatCookies | 17:6ae90788cc2b | 338 | leftHallSensor.rise(&GetTime_L); |
FatCookies | 17:6ae90788cc2b | 339 | rightHallSensor.rise(&GetTime_R); |
FatCookies | 17:6ae90788cc2b | 340 | } |
FatCookies | 17:6ae90788cc2b | 341 | |
FatCookies | 17:6ae90788cc2b | 342 | void GetTime_L(){ |
FatCookies | 17:6ae90788cc2b | 343 | Time_L=t1.read_us(); |
FatCookies | 17:6ae90788cc2b | 344 | t1.reset(); |
FatCookies | 17:6ae90788cc2b | 345 | } |
FatCookies | 17:6ae90788cc2b | 346 | |
FatCookies | 17:6ae90788cc2b | 347 | void GetTime_R(){ |
FatCookies | 17:6ae90788cc2b | 348 | Time_R=t2.read_us(); |
FatCookies | 17:6ae90788cc2b | 349 | t2.reset(); |
FatCookies | 17:6ae90788cc2b | 350 | } |
FatCookies | 17:6ae90788cc2b | 351 | |
FatCookies | 17:6ae90788cc2b | 352 | #if USE_COMMS |
FatCookies | 17:6ae90788cc2b | 353 | void sendBattery() { |
FatCookies | 17:6ae90788cc2b | 354 | |
FatCookies | 17:6ae90788cc2b | 355 | if(frame_counter % 256 == 0) { |
FatCookies | 17:6ae90788cc2b | 356 | float level = TFC_ReadBatteryVoltage() * 6.25; |
FatCookies | 17:6ae90788cc2b | 357 | pc.putc('J'); |
FatCookies | 17:6ae90788cc2b | 358 | thing.a = level; |
FatCookies | 17:6ae90788cc2b | 359 | pc.putc(thing.bytes[0]); |
FatCookies | 17:6ae90788cc2b | 360 | pc.putc(thing.bytes[1]); |
FatCookies | 17:6ae90788cc2b | 361 | pc.putc(thing.bytes[2]); |
FatCookies | 17:6ae90788cc2b | 362 | pc.putc(thing.bytes[3]); |
FatCookies | 17:6ae90788cc2b | 363 | } |
FatCookies | 17:6ae90788cc2b | 364 | } |
FatCookies | 17:6ae90788cc2b | 365 | |
FatCookies | 17:6ae90788cc2b | 366 | void sendString(const char *format, ...) { |
FatCookies | 17:6ae90788cc2b | 367 | va_list arg; |
FatCookies | 17:6ae90788cc2b | 368 | |
FatCookies | 17:6ae90788cc2b | 369 | pc.putc('E'); |
FatCookies | 17:6ae90788cc2b | 370 | va_start (arg, format); |
FatCookies | 17:6ae90788cc2b | 371 | pc.vprintf(format,arg); |
FatCookies | 17:6ae90788cc2b | 372 | va_end (arg); |
FatCookies | 17:6ae90788cc2b | 373 | pc.putc(0); |
FatCookies | 17:6ae90788cc2b | 374 | } |
FatCookies | 17:6ae90788cc2b | 375 | |
maximusismax | 8:7c5e6b1e7aa5 | 376 | inline void sendImage() { |
maximusismax | 8:7c5e6b1e7aa5 | 377 | //Only send 1/3 of camera frames to GUI program |
maximusismax | 8:7c5e6b1e7aa5 | 378 | if((frame_counter % 3) == 0) { |
maximusismax | 8:7c5e6b1e7aa5 | 379 | pc.putc('H'); |
FatCookies | 15:ccde02f96449 | 380 | if(sendCam == 0) { |
FatCookies | 15:ccde02f96449 | 381 | for(i = 0; i < 128; i++) { |
FatCookies | 17:6ae90788cc2b | 382 | pc.putc((int8_t)(CLOSE_CAMERA[i] >> 4) & 0xFF); |
FatCookies | 15:ccde02f96449 | 383 | } |
FatCookies | 15:ccde02f96449 | 384 | } else { |
FatCookies | 15:ccde02f96449 | 385 | for(i = 0; i < 128; i++) { |
FatCookies | 17:6ae90788cc2b | 386 | pc.putc((int8_t)(LOOKAHEAD_CAMERA[i] >> 4) & 0xFF); |
FatCookies | 15:ccde02f96449 | 387 | } |
FatCookies | 15:ccde02f96449 | 388 | } |
FatCookies | 13:4e77264f254a | 389 | sendBattery(); |
FatCookies | 13:4e77264f254a | 390 | } |
FatCookies | 13:4e77264f254a | 391 | |
FatCookies | 13:4e77264f254a | 392 | frame_counter++; |
FatCookies | 13:4e77264f254a | 393 | } |
FatCookies | 13:4e77264f254a | 394 | |
FatCookies | 13:4e77264f254a | 395 | inline void sendSpeeds() { |
FatCookies | 17:6ae90788cc2b | 396 | |
lh14g13 | 19:65f0b6febc23 | 397 | /*float en = getLineEntropy(); |
FatCookies | 15:ccde02f96449 | 398 | |
FatCookies | 15:ccde02f96449 | 399 | if(onTrack) { |
FatCookies | 15:ccde02f96449 | 400 | if(en <= 14000) { |
FatCookies | 15:ccde02f96449 | 401 | onTrack = false; |
FatCookies | 15:ccde02f96449 | 402 | sendString("offfffffffffffff"); |
FatCookies | 15:ccde02f96449 | 403 | TFC_SetMotorPWM(0.0,0.0); |
FatCookies | 15:ccde02f96449 | 404 | TFC_HBRIDGE_DISABLE; |
FatCookies | 15:ccde02f96449 | 405 | } |
FatCookies | 15:ccde02f96449 | 406 | } else { |
FatCookies | 15:ccde02f96449 | 407 | if(en > 14000) { |
FatCookies | 15:ccde02f96449 | 408 | onTrack = true; |
FatCookies | 15:ccde02f96449 | 409 | sendString("ON TRACK"); |
FatCookies | 15:ccde02f96449 | 410 | } |
lh14g13 | 19:65f0b6febc23 | 411 | }*/ |
FatCookies | 15:ccde02f96449 | 412 | |
FatCookies | 14:13085e161dd1 | 413 | |
FatCookies | 13:4e77264f254a | 414 | pc.putc('B'); |
lh14g13 | 19:65f0b6febc23 | 415 | thing.a = wL * WHEEL_RADIUS; |
FatCookies | 12:da96e2f87465 | 416 | pc.putc(thing.bytes[0]); |
FatCookies | 12:da96e2f87465 | 417 | pc.putc(thing.bytes[1]); |
FatCookies | 12:da96e2f87465 | 418 | pc.putc(thing.bytes[2]); |
FatCookies | 12:da96e2f87465 | 419 | pc.putc(thing.bytes[3]); |
lh14g13 | 19:65f0b6febc23 | 420 | thing.a = wR * WHEEL_RADIUS; |
FatCookies | 13:4e77264f254a | 421 | pc.putc(thing.bytes[0]); |
FatCookies | 13:4e77264f254a | 422 | pc.putc(thing.bytes[1]); |
FatCookies | 13:4e77264f254a | 423 | pc.putc(thing.bytes[2]); |
FatCookies | 13:4e77264f254a | 424 | pc.putc(thing.bytes[3]); |
maximusismax | 8:7c5e6b1e7aa5 | 425 | } |
maximusismax | 8:7c5e6b1e7aa5 | 426 | |
FatCookies | 13:4e77264f254a | 427 | |
maximusismax | 8:7c5e6b1e7aa5 | 428 | inline void handleComms() { |
maximusismax | 8:7c5e6b1e7aa5 | 429 | if(curr_cmd != 0) { |
FatCookies | 4:4afa448c9cce | 430 | switch(curr_cmd) { |
FatCookies | 4:4afa448c9cce | 431 | case 'A': |
FatCookies | 4:4afa448c9cce | 432 | if(xb.cBuffer->available() >= 3) { |
FatCookies | 4:4afa448c9cce | 433 | char p = xb.cBuffer->read(); |
FatCookies | 4:4afa448c9cce | 434 | char i = xb.cBuffer->read(); |
FatCookies | 4:4afa448c9cce | 435 | char d = xb.cBuffer->read(); |
FatCookies | 12:da96e2f87465 | 436 | servo_pid.Kp = p/25.0f; |
FatCookies | 12:da96e2f87465 | 437 | servo_pid.Ki = i/25.0f; |
FatCookies | 12:da96e2f87465 | 438 | servo_pid.Kd = d/25.0f; |
FatCookies | 13:4e77264f254a | 439 | sendString("pid= Kp: %f, Ki: %f, Kd: %f, p: %u, i: %u, d: %u", servo_pid.Kp, servo_pid.Ki, servo_pid.Kd, p, i, d); |
maximusismax | 8:7c5e6b1e7aa5 | 440 | |
FatCookies | 4:4afa448c9cce | 441 | curr_cmd = 0; |
FatCookies | 4:4afa448c9cce | 442 | } |
FatCookies | 4:4afa448c9cce | 443 | break; |
FatCookies | 4:4afa448c9cce | 444 | |
FatCookies | 4:4afa448c9cce | 445 | case 'F': |
FatCookies | 6:b0e160c51013 | 446 | if(xb.cBuffer->available() >= 1) { |
FatCookies | 4:4afa448c9cce | 447 | char a = xb.cBuffer->read(); |
lh14g13 | 19:65f0b6febc23 | 448 | //speed = a/255; |
lh14g13 | 19:65f0b6febc23 | 449 | speed = (a/0.025f)/50.f; |
lh14g13 | 19:65f0b6febc23 | 450 | //TFC_SetMotorPWM(speed,speed); |
FatCookies | 13:4e77264f254a | 451 | sendString("s = %u %f",a, speed); |
FatCookies | 4:4afa448c9cce | 452 | curr_cmd = 0; |
FatCookies | 4:4afa448c9cce | 453 | } |
FatCookies | 4:4afa448c9cce | 454 | break; |
FatCookies | 4:4afa448c9cce | 455 | |
FatCookies | 4:4afa448c9cce | 456 | default: |
FatCookies | 13:4e77264f254a | 457 | // Unrecognised command |
FatCookies | 13:4e77264f254a | 458 | curr_cmd = 0; |
FatCookies | 4:4afa448c9cce | 459 | break; |
FatCookies | 4:4afa448c9cce | 460 | } |
FatCookies | 4:4afa448c9cce | 461 | } |
FatCookies | 4:4afa448c9cce | 462 | |
FatCookies | 6:b0e160c51013 | 463 | if(xb.cBuffer->available() > 0 && curr_cmd == 0) { |
lh14g13 | 18:0095a3a8f8e4 | 464 | //Start car |
FatCookies | 4:4afa448c9cce | 465 | char cmd = xb.cBuffer->read(); |
FatCookies | 4:4afa448c9cce | 466 | if(cmd == 'D') { |
FatCookies | 17:6ae90788cc2b | 467 | ALIGN_SERVO; |
FatCookies | 4:4afa448c9cce | 468 | TFC_HBRIDGE_ENABLE; |
lh14g13 | 19:65f0b6febc23 | 469 | right_motor_pid.desired_value=speed; |
lh14g13 | 19:65f0b6febc23 | 470 | left_motor_pid.desired_value=speed; |
FatCookies | 12:da96e2f87465 | 471 | servo_pid.integral = 0; |
lh14g13 | 18:0095a3a8f8e4 | 472 | test.start(); |
lh14g13 | 18:0095a3a8f8e4 | 473 | lapNo =0; |
FatCookies | 6:b0e160c51013 | 474 | |
FatCookies | 4:4afa448c9cce | 475 | } else if (cmd == 'C') { |
FatCookies | 4:4afa448c9cce | 476 | TFC_SetMotorPWM(0.0,0.0); |
lh14g13 | 19:65f0b6febc23 | 477 | right_motor_pid.desired_value=0; |
lh14g13 | 19:65f0b6febc23 | 478 | left_motor_pid.desired_value=0; |
FatCookies | 4:4afa448c9cce | 479 | TFC_HBRIDGE_DISABLE; |
lh14g13 | 18:0095a3a8f8e4 | 480 | endTest(); |
FatCookies | 4:4afa448c9cce | 481 | } else if(cmd == 'A') { |
FatCookies | 4:4afa448c9cce | 482 | curr_cmd = 'A'; |
FatCookies | 4:4afa448c9cce | 483 | } else if(cmd == 'F') { |
FatCookies | 4:4afa448c9cce | 484 | curr_cmd = 'F'; |
FatCookies | 15:ccde02f96449 | 485 | } else if(cmd == 'K') { |
FatCookies | 15:ccde02f96449 | 486 | sendCam = ~sendCam; |
FatCookies | 4:4afa448c9cce | 487 | } |
FatCookies | 4:4afa448c9cce | 488 | |
FatCookies | 4:4afa448c9cce | 489 | } |
maximusismax | 8:7c5e6b1e7aa5 | 490 | } |
lh14g13 | 18:0095a3a8f8e4 | 491 | |
lh14g13 | 18:0095a3a8f8e4 | 492 | float testSpeed(float speed) |
lh14g13 | 18:0095a3a8f8e4 | 493 | { |
lh14g13 | 18:0095a3a8f8e4 | 494 | // search: Speed Increase |
lh14g13 | 18:0095a3a8f8e4 | 495 | // every time the car sees the stop start the speed of the car will increase |
lh14g13 | 18:0095a3a8f8e4 | 496 | // this can occur on stop start trigger. |
lh14g13 | 18:0095a3a8f8e4 | 497 | // may need to send the speed back to the telemetry. |
lh14g13 | 18:0095a3a8f8e4 | 498 | if (speed>0.4) |
lh14g13 | 18:0095a3a8f8e4 | 499 | { |
lh14g13 | 18:0095a3a8f8e4 | 500 | speed+=0.05; |
lh14g13 | 18:0095a3a8f8e4 | 501 | } |
lh14g13 | 18:0095a3a8f8e4 | 502 | |
lh14g13 | 18:0095a3a8f8e4 | 503 | else |
lh14g13 | 18:0095a3a8f8e4 | 504 | { |
lh14g13 | 18:0095a3a8f8e4 | 505 | speed+=0.1; |
lh14g13 | 18:0095a3a8f8e4 | 506 | |
lh14g13 | 18:0095a3a8f8e4 | 507 | } |
lh14g13 | 18:0095a3a8f8e4 | 508 | |
lh14g13 | 18:0095a3a8f8e4 | 509 | |
lh14g13 | 18:0095a3a8f8e4 | 510 | sendString("s = %f", speed); |
lh14g13 | 18:0095a3a8f8e4 | 511 | return speed; |
lh14g13 | 18:0095a3a8f8e4 | 512 | |
lh14g13 | 18:0095a3a8f8e4 | 513 | } |
lh14g13 | 18:0095a3a8f8e4 | 514 | |
lh14g13 | 18:0095a3a8f8e4 | 515 | |
lh14g13 | 18:0095a3a8f8e4 | 516 | |
lh14g13 | 18:0095a3a8f8e4 | 517 | int lapTime() |
lh14g13 | 19:65f0b6febc23 | 518 | { |
lh14g13 | 18:0095a3a8f8e4 | 519 | // function which sends the lap time back to the telemetry. |
lh14g13 | 18:0095a3a8f8e4 | 520 | float newTime= test.read(); |
lh14g13 | 18:0095a3a8f8e4 | 521 | lapNo += 1; |
lh14g13 | 18:0095a3a8f8e4 | 522 | float lapTime= newTime-oldTime; |
lh14g13 | 18:0095a3a8f8e4 | 523 | float avgTime= newTime/lapNo; |
lh14g13 | 18:0095a3a8f8e4 | 524 | |
lh14g13 | 19:65f0b6febc23 | 525 | sendString("For lap number: %d Lap Time: %f Avergae time: %f \n\r", lapNo,lapTime,avgTime); |
lh14g13 | 18:0095a3a8f8e4 | 526 | |
lh14g13 | 18:0095a3a8f8e4 | 527 | // OH WHAT UP IT'S DAT BOI!!!! |
lh14g13 | 18:0095a3a8f8e4 | 528 | return 0; |
lh14g13 | 18:0095a3a8f8e4 | 529 | } |
lh14g13 | 18:0095a3a8f8e4 | 530 | |
lh14g13 | 18:0095a3a8f8e4 | 531 | |
lh14g13 | 18:0095a3a8f8e4 | 532 | void endTest() |
lh14g13 | 18:0095a3a8f8e4 | 533 | {// This runs when the car has stopped, this should give the final elapsed time and othere things. this also stops the timer |
lh14g13 | 18:0095a3a8f8e4 | 534 | |
lh14g13 | 18:0095a3a8f8e4 | 535 | float time= test.read(); |
lh14g13 | 18:0095a3a8f8e4 | 536 | |
lh14g13 | 19:65f0b6febc23 | 537 | sendString("Laps done: %d Time elapsed: %f Average time: %f \n\r",lapNo, time,float (time/lapNo)); |
lh14g13 | 18:0095a3a8f8e4 | 538 | test.stop(); |
lh14g13 | 18:0095a3a8f8e4 | 539 | |
lh14g13 | 18:0095a3a8f8e4 | 540 | |
lh14g13 | 19:65f0b6febc23 | 541 | } |
lh14g13 | 18:0095a3a8f8e4 | 542 | |
lh14g13 | 18:0095a3a8f8e4 | 543 | |
lh14g13 | 18:0095a3a8f8e4 | 544 | |
lh14g13 | 18:0095a3a8f8e4 | 545 | |
lh14g13 | 18:0095a3a8f8e4 | 546 | |
FatCookies | 17:6ae90788cc2b | 547 | #endif |