Earth gravity added to calculations.
[speedfreak] / Client / calculate.cpp
index 781f7f9..aa579ec 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Calculate class to process accelerometer data
+ *
+ * @author      Kai Rasilainen
+ * @copyright   (c) 2010 Speed Freak team
+ * @license     http://opensource.org/licenses/gpl-license.php GNU Public License
+ */
+
 #include "calculate.h"
 #include <math.h>
 
 
 const double G_ACCELERATION = 9.80665;
 const double SECONDS_IN_HOUR = 3600;
+const double AIR_DENSITY = 1.225;
+const double WATTS_PER_HORSEPOWER = 745.69987158227025;
 
-Calculate::Calculate() {
+const double carFrontalArea = 1.5;
+const double dragCoefficient = 0.31;
+const int carWeight = 850;
 
+Calculate::Calculate()
+{
     this->reset();
-
 }
 
-Calculate::~Calculate() {
-}
+Calculate::~Calculate()
+{
 
-void Calculate::reset() {
+}
 
+void Calculate::reset()
+{
     averageSpeed = 0;
     currentSpeed = 0;
     distanceTraveled = 0;
@@ -28,135 +43,235 @@ void Calculate::reset() {
     lastSpeed = 0;
     numOfIterations = 0;
     totalTime = 0;
+    count = 0;
+
+    speedCheckPoints.append(10);
+    speedCheckPoints.append(20);
+    speedCheckPoints.append(30);
+    speedCheckPoints.append(40);
+
+}
+
+
+/**
+  * This is a main function for calculating various parameters. Accelerometer
+  * provides currentAcceleration and calling function measures time (seconds).
+  * This function should be called 20-30 times/second to minimize
+  * calculation error.
+
+  * To be added: ---
+  */
+void Calculate::calculateParameters(double currentAcceleration, double seconds)
+{
+    double force, power1, power2;
+
+    currentAcceleration *= G_ACCELERATION;
+    numOfIterations++;
+    totalTime = (totalTime + seconds);
+
+    // v=v0 + a*t
+    // v(n) = v(n-1)+(a(n) + a(n-1))*(seconds)/2
+
+    // First integration of acceleration provides speed
+    currentSpeed = (lastSpeed + (((currentAcceleration + lastAcceleration) * seconds) / 2));
+
+    // Second integration: distance.
+    distanceTraveled = (lastDistance + (((currentSpeed + lastSpeed) * seconds) / 2));
+
+    // Average speed
+    averageSpeed = (distanceTraveled / totalTime);
+
+    // F=ma
+    force = (carWeight * currentAcceleration);
+
+    power1 = (force * currentSpeed);
+
+    power2 = ((AIR_DENSITY * (pow(currentSpeed, 3)
+             * (carFrontalArea * dragCoefficient))) / 2);
+
+    currentPower = ((power1 + power2) / WATTS_PER_HORSEPOWER);
+
+    // Save peak power
+    if ((currentPower > peakPower))
+    {
+        peakPower = currentPower;
+    }
+
+    if ((currentPower > 0))
+    {
+        averagePower = (averagePower + currentPower);
+    }
+    else
+    {
+        numOfIterations--;
+    }
+
+    // Checkpoints
+    if ((lastSpeed == 0))
+    {
+        lastCheckpoint = 0;
+    }
+
+    // List of checkpoints
+    if (!(speedCheckPoints.isEmpty()))
+    {
+        foreach (double speed, speedCheckPoints)
+        {
+            if ((lastCheckpoint != floor(speed)) && (floor(currentSpeed) == floor(speed)))
+            {
+                emit checkPointReached(totalTime, currentSpeed);
+                lastCheckpoint = floor(currentSpeed);
+            }
+        }
+    }
+
+    // Check for movement
+    accelStoppedCheck(currentAcceleration);
+
+    lastSpeed = currentSpeed;
+    lastAcceleration = currentAcceleration;
+    lastDistance = distanceTraveled;
+}
+
+/**
+  * This function checks if acceleration has stopped for
+  * a short period of time. Velocity is set to zero to avoid
+  * distance errors.
+  */
+void Calculate::accelStoppedCheck(double currentAcceleration)
+{
+
+    // counting number of acceleration samples that equals zero
+    if (currentAcceleration==0) {
+        count++;
+    } else {
+        count = 0;
+    }
+
+    // if count exceeds 15, we assume that velocity is zero
+    if (count >= 15)
+    {
+        currentSpeed=0;
+    }
 }
 
-/* Getters and setters
-   */
+// Getters and setters
 
-double Calculate::AverageSpeed()
+double Calculate::getAverageSpeed()
 {
     return averageSpeed;
 }
-void Calculate::AverageSpeed(double value)
+
+void Calculate::setAverageSpeed(double value)
 {
     averageSpeed = value;
 }
-double Calculate::CurrentSpeed()
+
+double Calculate::getCurrentSpeed()
 {
     return currentSpeed;
 }
-void Calculate::CurrentSpeed(double value)
+
+void Calculate::setCurrentSpeed(double value)
 {
     currentSpeed = value;
 }
-double Calculate::DistanceTraveled()
+
+double Calculate::getDistanceTraveled()
 {
     return distanceTraveled;
 }
-void Calculate::DistanceTraveled(double value)
+
+void Calculate::setDistanceTraveled(double value)
 {
     distanceTraveled = value;
 }
-double Calculate::LastAcceleration()
+
+double Calculate::getLastAcceleration()
 {
     return lastAcceleration;
 }
-void Calculate::LastAcceleration(double value)
+
+void Calculate::setLastAcceleration(double value)
 {
     lastAcceleration = value;
 }
-double Calculate::LastDistance()
+
+double Calculate::getLastDistance()
 {
     return lastDistance;
 }
-void Calculate::LastDistance(double value)
+
+void Calculate::setLastDistance(double value)
 {
     lastDistance = value;
 }
-double Calculate::LastSpeed()
+
+double Calculate::getLastSpeed()
 {
     return lastSpeed;
 }
-void Calculate::LastSpeed(double value)
+
+void Calculate::setLastSpeed(double value)
 {
     lastSpeed = value;
 }
-long Calculate::NumOfIterations()
+
+long Calculate::getNumOfIterations()
 {
     return numOfIterations;
 }
-void Calculate::NumOfIterations(long value)
+
+void Calculate::setNumOfIterations(long value)
 {
     numOfIterations = value;
 }
-double Calculate::TotalTime()
+
+double Calculate::getTotalTime()
 {
     return totalTime;
 }
-void Calculate::TotalTime(double value)
+
+void Calculate::setTotalTime(double value)
 {
     totalTime = value;
 }
 
-/*
-  This is a main function for calculating various parameters. Accelerometer
-  provides currentAcceleration and calling function measures time (seconds).
-  This function should be called 20-30 times/second to minimize
-  calculation error.
-
-  To be added: params like horsepower.
-  */
-void Calculate::CalculateParameters(double currentAcceleration, double seconds)
+double Calculate::getCurrentPower()
 {
-    numOfIterations++;
-    totalTime = (totalTime + seconds);
-
-    // v=v0 + a*t
-    // v(n) = v(n-1)+(a(n) + a(n-1))*(seconds)/2
-
-    /* First integration of acceleration provides speed
-       */
-    currentSpeed = (lastSpeed + (((currentAcceleration + lastAcceleration) * seconds) / 2));
-
-    /* Second integration: distance.
-       */
-    distanceTraveled = (lastDistance + (((currentSpeed + lastSpeed) * seconds) / 2));
-
-    /* Average speed
-       */
-    averageSpeed = (distanceTraveled / totalTime);
+    return currentPower;
+}
 
-    /* Check for movement
-           */
-    accelStoppedCheck(currentAcceleration);
+void Calculate::setCurrentPower(double value)
+{
+    currentPower = value;
+}
 
-    lastSpeed = currentSpeed;
-    lastAcceleration = currentAcceleration;
-    lastDistance = distanceTraveled;
+double Calculate::getPeakPower()
+{
+    return peakPower;
 }
 
-/**
-  * This function checks if acceleration has stopped for
-  * a short period of time. Velocity is set to zero to avoid
-  * distance errors.
-  */
-void Calculate::accelStoppedCheck(double currentAcceleration) {
+void Calculate::setPeakPower(double value)
+{
+    peakPower = value;
+}
 
-    // counting number of acceleration samples that equals zero
-    if (currentAcceleration==0)
+double Calculate::getAveragePower()
+{
+    if (numOfIterations > 0)
     {
-        count++;
+        return (averagePower/numOfIterations);
     }
     else
     {
-        count = 0;
+        return 0;
     }
+}
 
-    // if count exceeds 25, we assume that velocity is zero
-    if (count >= 25)
-    {
-        currentSpeed=0;
-    }
+void Calculate::setAveragePower(double value)
+{
+    averagePower = value;
 }