car using PID from centre line

Dependencies:   FRDM-TFC mbed CBuffer XBEE mbed_angular_speed motor2 MMA8451Q

Fork of KL25Z_Camera_Test by GDP 4

Revision:
31:1a06c9e1985e
Parent:
29:b5b31256572b
Child:
32:6829684f8c4d
--- a/main.cpp	Tue Jan 10 11:24:13 2017 +0000
+++ b/main.cpp	Wed Jan 11 11:36:56 2017 +0000
@@ -121,7 +121,6 @@
     wR = 0;
     prevL = 0;
     prevR = 0;
- 
 }
 
 void initPID(pid_instance* pid, float Kp, float Ki, float Kd) {
@@ -139,29 +138,35 @@
 
     bool leftSeen;
     bool rightSeen;
-    
+
+//Function which calcuates how far to the left/right of the centre of the track the car is
+//Takes data from either camera, and passes some variables by reference, which will hold
+//the indices holding the locations of the left and right edges of the track
 inline float findCentreValue(volatile uint16_t * cam_data, uint8_t &l, uint8_t &r) {
    
-    diff = 0;
-    prev = -1;
+    diff = 0; //Holds difference in intensity between consecutive pixels
+    prev = -1; //Holds index of last inspected pixel
 
+    //Used for crossroads navigation, holds info on which edges of the track are observed
     leftSeen = false;
     rightSeen = false;
-        
+    
+    //Starting in the middle index, step left, inspecting the the edge of the track
     for(i = 63; i > 0; i--) {
         curr_left = (uint8_t)(cam_data[i] >> 4) & 0xFF;              
         diff = prev - curr_left;
+        //Check incorporates a combination of looking at the difference in intensities
+        //and whether the pixels intensity is less than a threshold, corresponding to the black edge
         if(abs(diff) >= CAM_DIFF && curr_left <= CAM_THRESHOLD && prev != -1) {
-            l = i;
+            l = i; //Record the index where the edge is observed
             leftSeen = true;
             break;
         }
-        prev = curr_left;
+        prev = curr_left; //Update previous value for the loop
     }
     
-        
-    
     prev = -1;
+    //As before, start in the middle but this time step rightwards in the image
     for(i = 64; i < 128; i++) {
         curr_right = (uint8_t)(cam_data[i] >> 4) & 0xFF;
         int diff = prev - curr_right;
@@ -173,26 +178,32 @@
         prev = curr_right;
     }
     
+    //If both edges are not visible, we are likely in a crossroads
     if(!rightSeen && !leftSeen) {
         sendString("lost edges");
-        ALIGN_SERVO;
-        servo_pid.integral = 0;    
+        ALIGN_SERVO; //Straighten wheels so we go straight through the crossroads
+        servo_pid.integral = 0;
     }
     
-    //Calculate how left/right we are   
+    //Calculate how left/right from the centre line we are
     return (64 - ((l+r)/2))/64.f;
 }
 
+//Unused function currently
+//Was used to establish whether we are in a corner, by inspecting a buffer of
+//centre line values
 inline void handleCornering() {
     
+    //Get current value of how left/right of centre line we are on the track
     float lookaheadMeasuredValue = findCentreValue(LOOKAHEAD_CAMERA, farLeft, farRight);
     
     measuredValBuffer[frame_counter % 64] = servo_pid.measured_value;
     
     int count = 0;
     for(i = 0; i < 10; i++) {
+        //Step through the buffer, using modulus operator
         float val = abs(measuredValBuffer[(frame_counter - i) % 64]);
-        if(val > 0.09) {
+        if(val > 0.09) { //If the value exceeds a certain value (obtained experimentally), we are in a corner
             count++;
         }
     } 
@@ -241,6 +252,8 @@
     
 }
 
+//Unused function currently
+//Was used to estimate whether the stop marker was seen
 inline float getLineEntropy() {
     float entropy = 0;
     float last = (int8_t)(CLOSE_CAMERA[0] >> 4) & 0xFF;
@@ -259,7 +272,7 @@
     pid->p_error = pid->pid_error;
     
     if(pid->integral > 1.0f) {
-        pid->integral = 1.0f;   
+        pid->integral = 1.0f;
     }
     if(pid->integral < -1.0f    ) {
         pid->integral = -1.0f;   
@@ -278,7 +291,7 @@
     wR=Get_Speed(Time_R);
     
     // Check if left wheel is slipping/giving an abnormal reading and ignore reading
-    if(wL - prevL < 1.2/0.025) {
+    if(wL - prevL < 1.2/0.025) { //<3 magic numbers: 48....?
         left_motor_pid.measured_value = wL;
     }
     if(wR - prevR < 1.2/0.025) {
@@ -299,7 +312,8 @@
     else //Unhappy PID state
     {        
         //sendString("out = %f p_err = %f", servo_pid.output, servo_pid.p_error);
-        ALIGN_SERVO;
+        //ALIGN_SERVO;
+        //Could cause the car to be travelling along one side of the track rather than in the middle
         if(servo_pid.output >= 1.0f) {
             TFC_SetServo(0, 0.9f);
             servo_pid.output = 1.0f;
@@ -333,57 +347,16 @@
 }
 
 inline void handleStartStop() {
+
+    //Function to detect the NXP cup stop marker
     
-    //v1:
-    //Hacky way to detect the start/stop signal
-    /*if(right - left < 60) {
-        sendString("START STOP!!");
-
-        TFC_SetMotorPWM(0.f,0.f);
-        TFC_HBRIDGE_DISABLE;
-        startstop = 0;
-    }*/
-        
-    //----------------------------START/STOP v2-----------------------------
-    //New method plan:
-    //Start at the centre of the image
-    //Look for 2 transitions (B->W OR W->B) - ignoring whether the centre pixel was black or white
-    //this should efficiently detect whether the marker is visible, and shouldn't give too many false positives
-    //May need to fiddle with the track width initial check, or disbale it entirely.
-    //NB: May want to incorporate this into findCentreValue(), it looks like they will be operating in similar ways on the exact same data...
-    /*
-    uint8_t lastPixel, currentPixel;
-    lastPixel = -1; //or 0?
-    bool startStopLeft = false;
-    bool startStopRight = false
-    //So:
-    //1. Starting at the middle, step left, looking for 2 transitions
-    for(int i = 63; i > 0; i--) {
-        currentPixel = (uint8_t)(CLOSE_CAMERA[i] >> 4) & 0xFF; //Cast to signed or unsigned? Edge detection code has signed, but it puts it in an unsigned variable...
-        if((lastPixel - currentPixel) > 10) { //1st transition
-            for (int j = i; j > 0; j--) { //Keep going until 2nd transition
-                if((lastPixel - currentPixel) > 10) { //2nd transition
-                    //Set flag that 2 transitions on the left side are identified
-                    startStopLeft = true;
-                    //goto finishLeft;
-                }
-            }
-            
-        }
-        startStopLeft = false;
-        lastPixel = currentPixel;
-    }
-    //finishLeft:
-    */
-    
-    //v2.5:--------------
-    
-    int slower = 0;
-    int difference = 0;
+    int slower = 0; //Only send a string every few frames
+    int difference = 0; //Holds the difference between intensities of consecutive pixels
     int lastPixel, currentPixel, transitionsSeen;
     lastPixel = -1;
     transitionsSeen = 0;
-    //Starting  near the left edge, step right, counting transitions. If there are 4, it is the marker (what about 3?)
+    //Starting  near the left edge, step right, counting transitions.
+    //If there are several (exact value varies, best established experimentally), it is the marker
     for(int i = 30; i < 98; i++) {
         currentPixel = (int)(CLOSE_CAMERA[i] >> 4) & 0xFF;
         difference = lastPixel - currentPixel;
@@ -393,9 +366,11 @@
         }
         lastPixel = currentPixel;
     }
+    //Was used to send an indication that the marker was seen, useful for debugging
     //if (slower % 1000 == 0) {
         //sendString("Transitions seen: %d", transitionsSeen);
     //}
+    //slower++;
     if(transitionsSeen >= 5) {
         //Stop the car!
         sendString("Start/stop seen");
@@ -403,8 +378,6 @@
         TFC_HBRIDGE_DISABLE;
         lapTime();
     }
-  //  slower++;
-    
 }