David's dead reckoning code for the LVBots competition on March 6th. Uses the mbed LPC1768, DRV8835, QTR-3RC, and two DC motors with encoders.

Dependencies:   PololuEncoder Pacer mbed GeneralDebouncer

Files at this revision

API Documentation at this revision

Comitter:
DavidEGrayson
Date:
Sat Jul 27 20:58:46 2019 +0000
Parent:
41:3ead1dd2cc3a
Child:
43:0e985a58f174
Commit message:
Calibrate L3G using a buffer of 1000 zero-rate readings. Measured a drift of -1.850 degrees over 3 minutes (-0.01 degree per second).

Changed in this revision

l3g.cpp Show annotated file Show diff for this revision Revisions of this file
l3g.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
test.h Show annotated file Show diff for this revision Revisions of this file
turn_sensor.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/l3g.cpp	Thu Jul 25 03:20:41 2019 +0000
+++ b/l3g.cpp	Sat Jul 27 20:58:46 2019 +0000
@@ -6,7 +6,7 @@
 
 I2C i2c(p9, p10);
 
-int address = 0xD6;
+const int address = 0xD6;
 
 int32_t l3gInit()
 {
@@ -92,4 +92,49 @@
     }
     
     return (int16_t)(data[1] << 8 | data[0]);
+}
+
+// The stuff below doesn't actually have anything to do with the L3G.
+
+#define L3G_CAL_COUNT_MAX 1000
+int8_t l3gCalBuffer[L3G_CAL_COUNT_MAX];
+uint32_t l3gCalCount = 0;
+uint32_t l3gCalReplayIndex = 0;
+
+int32_t l3gCalibrate()
+{
+    int32_t reading = l3gZRead();
+    
+    if (l3gCalCount < L3G_CAL_COUNT_MAX)
+    {
+        int8_t c;
+        if (reading > 127) { c = 127; }
+        else if (reading < -128) { c = -128; }
+        else { c = reading; }
+        l3gCalBuffer[l3gCalCount++] = c;
+    }
+    
+    return reading;
+}
+
+bool l3gCalibrateDone()
+{
+    return l3gCalCount >= L3G_CAL_COUNT_MAX;
+}
+
+void l3gCalibrateReset()
+{
+    l3gCalCount = 0;
+}
+
+int32_t l3gZReadCalibrated()
+{
+    int8_t zeroRate = 0;
+    if (l3gCalCount)
+    {
+      if (l3gCalReplayIndex >= l3gCalCount) { l3gCalReplayIndex = 0; }
+      zeroRate = l3gCalBuffer[l3gCalReplayIndex++];
+    }
+    
+    return l3gZRead() - zeroRate;
 }
\ No newline at end of file
--- a/l3g.h	Thu Jul 25 03:20:41 2019 +0000
+++ b/l3g.h	Sat Jul 27 20:58:46 2019 +0000
@@ -5,4 +5,14 @@
 int32_t l3gReadReg(char reg);
 int32_t l3gWriteReg(char reg, char value);
 int32_t l3gZRead();
-int32_t l3gZAvailable();
\ No newline at end of file
+int32_t l3gZAvailable();
+
+// Takes one reading and record it for the purposes of zero-rate calibrations.
+// Returns the reading just in case you want it for something.
+int32_t l3gCalibrate();
+
+bool l3gCalibrateDone();
+
+void l3gCalibrateReset();
+
+int32_t l3gZReadCalibrated();
--- a/main.cpp	Thu Jul 25 03:20:41 2019 +0000
+++ b/main.cpp	Sat Jul 27 20:58:46 2019 +0000
@@ -58,7 +58,7 @@
     //testMotorSpeed();
     //testLineSensors();
     //testL3g();
-    //testL3gAndCalibrate();
+    //testL3gAndShowAverage();
     testTurnSensor();
     //testReckoner();
     //testButtons();
@@ -72,7 +72,8 @@
     //testCloseness();
     //testLogger();
 
-    loadCalibration();
+    loadLineCalibration();
+    doGyroCalibration();
 
     doDeadReckoning();
 }
@@ -126,8 +127,17 @@
     }   
 }
 
+void doGyroCalibration()
+{
+    wait_ms(1000);  // Time for the robot to stop moving.
+    while (!l3gCalibrateDone())
+    {
+        l3gCalibrate();
+        wait_ms(2);
+    }
+}
 
-void loadCalibration()
+void loadLineCalibration()
 {
     /** QTR-3RC **/
     lineTracker.calibratedMinimum[0] =  100;
@@ -136,15 +146,6 @@
     lineTracker.calibratedMaximum[0] =  792;
     lineTracker.calibratedMaximum[1] =  807;
     lineTracker.calibratedMaximum[2] = 1000;    
-    
-    /** QTR-3A
-    lineTracker.calibratedMinimum[0] = 34872;
-    lineTracker.calibratedMinimum[1] = 29335;
-    lineTracker.calibratedMinimum[2] = 23845;
-    lineTracker.calibratedMaximum[0] = 59726;
-    lineTracker.calibratedMaximum[1] = 60110;
-    lineTracker.calibratedMaximum[2] = 58446;
-    **/
 }
 
 void updateReckonerFromEncoders()
--- a/main.h	Thu Jul 25 03:20:41 2019 +0000
+++ b/main.h	Sat Jul 27 20:58:46 2019 +0000
@@ -3,8 +3,10 @@
 #include "reckoner.h"
 #include "line_tracker.h"
 #include "logger.h"
+#include "turn_sensor.h"
 
-void loadCalibration();
+void loadLineCalibration();
+void doGyroCalibration();
 
 void waitForSignalToStart();
 void findLineAndCalibrate(); void findLine();  // two alternatives
@@ -24,4 +26,5 @@
 
 extern Reckoner reckoner;
 extern LineTracker lineTracker;
-extern Logger logger;
\ No newline at end of file
+extern TurnSensor turnSensor;
+extern Logger logger;
--- a/test.cpp	Thu Jul 25 03:20:41 2019 +0000
+++ b/test.cpp	Sat Jul 27 20:58:46 2019 +0000
@@ -208,7 +208,7 @@
     
     Pacer reportPacer(200000);
     
-    loadCalibration();
+    loadLineCalibration();
     uint16_t loopCount = 0;
     while(1)
     {
@@ -290,6 +290,8 @@
 
 void testReckoner()
 {
+    doGyroCalibration();
+    led1 = 1;
     Pacer reportPacer(100000);
     while(1)
     {
@@ -311,26 +313,32 @@
 void testTurnSensor()
 {
     pc.printf("Test turn sensor\r\n");
-    Pacer reportPacer(200000);
-    TurnSensor turnSensor;
+    led1 = 1;
+    doGyroCalibration();
+    //Pacer reportPacer(200000);  // 0.2 s
+    Pacer reportPacer(10000000);  // 10 s
+    Timer timer;
+    led2 = 1;
+    timer.start();
     turnSensor.start();
     while(1)
     {
         turnSensor.update();
         if (reportPacer.pace())
         {
-            pc.printf("%d\r\n", turnSensor.getAngleDegrees());
+            pc.printf("%u, %d, %d\r\n",
+              timer.read_ms(),
+              turnSensor.getAngleDegrees(),
+              turnSensor.getAngleMillidegrees());
         }
     }
 }
 
-void testL3gAndCalibrate()
+void testL3gAndShowAverage()
 {
     wait_ms(2000);
     Pacer reportPacer(750000);
     Pacer readingPacer(2000);
-    Timer timer;
-    timer.start();
     int32_t total = 0;
     int32_t readingCount = 0;
     while(1)
@@ -384,7 +392,7 @@
             reportedReading = false;
             if (gz > 100 || gz < -100)
             {
-                pc.printf("%d, %d\r\n", timer.read_us(), gz); 
+                pc.printf("%u, %d\r\n", timer.read_us(), gz); 
                 reportedReading = true;
             }
         }
@@ -395,7 +403,7 @@
 
         if (reportPacer.pace() && !reportedReading)
         {
-            pc.printf("%d, %d\r\n", timer.read_us(), gz);
+            pc.printf("%u, %d\r\n", timer.read_us(), gz);
             reportedReading = true;
         }
     }
--- a/test.h	Thu Jul 25 03:20:41 2019 +0000
+++ b/test.h	Sat Jul 27 20:58:46 2019 +0000
@@ -5,7 +5,7 @@
 void __attribute__((noreturn)) testMotorSpeed();
 void __attribute__((noreturn)) testLineSensors();
 void __attribute__((noreturn)) testL3g();
-void __attribute__((noreturn)) testL3gAndCalibrate();
+void __attribute__((noreturn)) testL3gAndShowAverage();
 void __attribute__((noreturn)) testTurnSensor();
 void __attribute__((noreturn)) testReckoner();
 void __attribute__((noreturn)) testButtons();
--- a/turn_sensor.cpp	Thu Jul 25 03:20:41 2019 +0000
+++ b/turn_sensor.cpp	Sat Jul 27 20:58:46 2019 +0000
@@ -18,19 +18,12 @@
 {
     if (l3gZAvailable() == 1)
     {
-        int32_t gz = l3gZRead();
+        int32_t gz = l3gZReadCalibrated();
         if (gz < -500000)
         {
             // error
             return;
-        }
-        
-        // The gyro zero rate on my robot, measured by testL3gAndCalibrate() on
-        // 2019-07-24 is about -6.5.  So let's add 6 half the time and add 7
-        // the other half of the time.  This is a big hack.
-        static uint8_t updateCount = 0;
-        updateCount++;
-        gz = gz + 6 + (updateCount & 1);
+        }        
 
         // The gyro on this robot is mounted upside down; account for that here so that
         // we can have counter-clockwise be a positive rotation.
--- a/turn_sensor.h	Thu Jul 25 03:20:41 2019 +0000
+++ b/turn_sensor.h	Sat Jul 27 20:58:46 2019 +0000
@@ -27,6 +27,11 @@
         return (((int32_t)angleUnsigned >> 16) * 360) >> 16;
     }
     
+    int32_t getAngleMillidegrees()
+    {
+        return ((int64_t)(int32_t)angleUnsigned * 360000) >> 32;
+    }
+    
     int16_t getRate()
     {
         return rate;