David's line following code from the LVBots competition, 2015.

Dependencies:   GeneralDebouncer Pacer PololuEncoder mbed

Fork of DeadReckoning by David Grayson

Files at this revision

API Documentation at this revision

Comitter:
DavidEGrayson
Date:
Wed Apr 15 23:56:52 2015 +0000
Parent:
51:b9f7243609d4
Child:
53:73565a3ef5c5
Commit message:
It learned the course, holy shit!

Changed in this revision

logger.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
test.cpp Show annotated file Show diff for this revision Revisions of this file
turn_sensor.h Show annotated file Show diff for this revision Revisions of this file
--- a/logger.h	Wed Apr 15 23:01:39 2015 +0000
+++ b/logger.h	Wed Apr 15 23:56:52 2015 +0000
@@ -18,10 +18,11 @@
     void log(struct LogEntry *);
     void dump();
     bool isFull();
+    int32_t getSize() { return entryIndex; }
     
     LogEntry entries[LOGGER_SIZE];
     
     // The index of the next entry to write to.
-    int32_t entryIndex;
+    uint32_t entryIndex;
 };
 
--- a/main.cpp	Wed Apr 15 23:01:39 2015 +0000
+++ b/main.cpp	Wed Apr 15 23:56:52 2015 +0000
@@ -21,6 +21,7 @@
 Logger logger;
 Pacer loggerPacer(50000);
 
+uint8_t lapsCompleted = 0;
 uint32_t totalEncoderCounts = 0;
 uint32_t nextLogEncoderCount = 0;
 const uint32_t logSpacing = 100;
@@ -73,8 +74,8 @@
     
     setLeds(1, 0, 0, 0);
     waitForSignalToStart();
-        
-    setLeds(0, 1, 0, 0);    // led4 gets set when it detects the start
+  
+    setLeds(0, 1, 0, 0);    // led3 and led4 get set by followLineSmart for debugging
     //followLineFast();
     followLineSmart();
     
@@ -234,7 +235,7 @@
     wait(0.2);
 }
 
-void updateMotorsToFollowLine()
+void updateMotorsToFollowLineSlow()
 {
     const int16_t drivingSpeed = 400;
     const int32_t followLineStrength = drivingSpeed * 5 / 4;
@@ -254,9 +255,8 @@
     motorsSpeedSet(speedLeft, speedRight);
 }
 
-void updateMotorsToFollowLineFast()
+void updateMotorsToFollowLineFast(int16_t drivingSpeed)
 {
-    const int16_t drivingSpeed = 1000;
     const int32_t followLineStrength = drivingSpeed * 5 / 4;
     static int16_t lastPosition = 1000;
 
@@ -295,7 +295,7 @@
         loggerService();
         
         lineTracker.read();
-        updateMotorsToFollowLineFast();
+        updateMotorsToFollowLineFast(1000);
         
         if (button1DefinitelyPressed())
         {
@@ -314,9 +314,59 @@
     return result;
 }
 
+bool onLongStraightPart()
+{
+    if (lapsCompleted == 0) { return false; }
+    
+    // Figure out what part of the log corresponds to our current situation.
+    uint32_t logIndex = totalEncoderCounts / logSpacing;
+    
+    if (logIndex >= logger.getSize())
+    {
+        // Should not happen.
+        return false;
+    }
+    
+    // To improve this, we could check that turnSensor.getAngle() matches what is in the log.
+
+    uint32_t angle1 = turnSensor.getAngleUnsigned();
+
+    // 1000 encoder ticks
+    const uint32_t lookAheadAmount = 2000 / logSpacing;
+    
+    // Figure out how far away the next turn is.
+    uint32_t i = logIndex;
+    while(1)
+    {
+        i++;
+        
+        if (i >= logger.getSize())
+        {
+            // reached the end the log
+            return false;
+        }
+
+        if (i > logIndex + lookAheadAmount)
+        {
+            // looked far enough ahead that we don't think there is a turn coming up soon
+            return true;
+        }
+        
+        
+        uint32_t angle2 = (uint16_t)logger.entries[i].turnAngle << 16;
+        if (abs((int32_t)(angle2 - angle1)) > turnAngle45)
+        {
+            // detected a turn
+            return false;
+        }
+    }
+}
+
 void followLineSmart()
 {
+    lapsCompleted = 0;   
     totalEncoderCounts = 0;
+
     Pacer reportPacer(200000);
     
     loadCalibration();
@@ -328,16 +378,42 @@
         loggerService();
         
         lineTracker.read();
-        updateMotorsToFollowLineFast();
+        
+        // By default, choose a cautious speed of 1000 (out of 1200).
+        int16_t speed = 1000;
+        
+        // Go fast if we know we are on a long straight part.
+        if (onLongStraightPart())
+        {
+            speed = 1200;
+            led3 = 1;
+        }
+        else
+        {
+            led3 = 0;
+        }
+        
+        
+        updateMotorsToFollowLineFast(speed);
 
         if (foundStart())
         {
+            // Another lap has been completed!
+            lapsCompleted = 1;
+            led4 = lapsCompleted & 1;
+
             reckoner.reset();
             turnSensor.reset();
             totalEncoderCounts = 0;
             nextLogEncoderCount = 0;
-            led4 = 1;
-        }        
+        }
+        
+        if (lapsCompleted == 3 && totalEncoderCounts > 2000)
+        {
+            // Classy move: know when you are done with the competition and stop automatically.
+            // (Of course, there is a risk that this will backfire!)
+            break;
+        }
         
         if (button1DefinitelyPressed())
         {
--- a/main.h	Wed Apr 15 23:01:39 2015 +0000
+++ b/main.h	Wed Apr 15 23:56:52 2015 +0000
@@ -9,10 +9,12 @@
 
 void waitForSignalToStart();
 void followLineFast();
-void updateMotorsToFollowLineFast();
+
+void updateMotorsToFollowLineFast(int16_t drivingSpeed);
+void updateMotorsToFollowLineSlow();
+
 void __attribute__((noreturn)) loggerReportLoop();
 
-void updateMotorsToFollowLine();
 void updateReckonerFromEncoders();
 void updateReckoner(TurnSensor &);
 void setLeds(bool v1, bool v2, bool v3, bool v4);
--- a/test.cpp	Wed Apr 15 23:01:39 2015 +0000
+++ b/test.cpp	Wed Apr 15 23:56:52 2015 +0000
@@ -215,8 +215,7 @@
         updateReckonerFromEncoders();
         bool lineVisiblePrevious = lineTracker.getLineVisible();
         lineTracker.read();
-        updateMotorsToFollowLine();
-        
+        updateMotorsToFollowLineSlow();
         loopCount += 1;
         
         if (lineVisiblePrevious != lineTracker.getLineVisible())
--- a/turn_sensor.h	Wed Apr 15 23:01:39 2015 +0000
+++ b/turn_sensor.h	Wed Apr 15 23:56:52 2015 +0000
@@ -17,6 +17,11 @@
         return (int32_t)angleUnsigned;
     }
     
+    uint32_t getAngleUnsigned()
+    {
+        return angleUnsigned;
+    }
+    
     int16_t getAngleDegrees()
     {
         return (((int32_t)angleUnsigned >> 16) * 360) >> 16;