Youtube video and text (draft).
[speedfreak] / Client / accelerometer.cpp
index 8733d32..c2f0bab 100644 (file)
@@ -1,16 +1,21 @@
-#include "accelerometer.h"
-#include "math.h"
+/*
+ * Accelerometer class to access the device accelerometer
+ *
+ * @author      Rikhard Kuutti <rikhard.kuutti@fudeco.com>
+ * @author      Kai Rasilainen <kai.rasilainen@fudeco.com>
+ * @author      Jukka Kurttila <jukka.kurttila@fudeco.com>
+ * @copyright   (c) 2010 Speed Freak team
+ * @license     http://opensource.org/licenses/gpl-license.php GNU Public License
+ */
 
-#include <QFile>
-#include <QString>
-#include <QRegExp>
-#include <QTimer>
+#include "accelerometer.h"
 
-#define kFilteringFactor    0.1
-#define kGravity            9.81
-#define kFileName           "/sys/class/i2c-adapter/i2c-3/3-001d/coord"
+#include <QDBusConnection>
+#include <QDBusInterface>
+#include <QDBusPendingReply>
 
-static int sampleIndex=0;
+#define kFilteringFactor 0.2
+#define kIterations      1024
 
 /**
  * Default constructor for Accelerometer class
@@ -18,27 +23,8 @@ static int sampleIndex=0;
  */
 Accelerometer::Accelerometer()
 {
-    calculate = new Calculate();
-
-    timer = new QTimer(this);
-    connect(timer, SIGNAL(timeout()), this, SLOT(processData()));
-    sampleRate = 40;
-    initValues();
-}
-
-/**
- * Constructor for Accelerometer class that takes accelerometer sample rate as parameter
- *
- * @param p_SampleRate the desired sample rate of accelerometer in milliseconds
- */
-Accelerometer::Accelerometer(int p_SampleRate)
-{
-    calculate = new Calculate();
-
-    timer = new QTimer(this);
-    connect(timer, SIGNAL(timeout()), this, SLOT(processData()));
-    sampleRate = p_SampleRate;
     initValues();
+    calibrateDialog = NULL;
 }
 
 /**
@@ -47,18 +33,8 @@ Accelerometer::Accelerometer(int p_SampleRate)
  */
 Accelerometer::~Accelerometer()
 {
-}
-
-/**
- * Start measuring
- *
- */
-void Accelerometer::start()
-{
-    initValues();
-    calibrate();
-    timer->start(sampleRate);
-    now.restart();
+    if(calibrateDialog)
+        delete calibrateDialog;
 }
 
 /**
@@ -67,27 +43,12 @@ void Accelerometer::start()
  */
 void Accelerometer::initValues()
 {
-    accelerationX=0;
-    accelerationY=0;
-    accelerationZ=0;
-    trueAccelerationX=0;
-    trueAccelerationY=0;
-    trueAccelerationZ=0;
-    previousAccelerationX=0;
-    previousAccelerationY=0;
-    previousAccelerationZ=0;
-    previousSpeed=0;
-    currentSpeed=0;
-    currentAcceleration=0;
-    previousAcceleration=0;
-    totalAcceleration=0;
-    intervalTime=0;
-    totalTime=0;
-    distanceTraveled=0;
-    lastDistanceTraveled=0;
-    averageSpeed=0;
-    sampleRate=0;
-    reverseAcceleration = false;
+    previousAccelerationX = 0;
+    previousAccelerationY = 0;
+    previousAccelerationZ = 0;
+    calibrationX = 0;
+    calibrationY = 0;
+    calibrationZ = 0;
 }
 
 /**
@@ -97,205 +58,99 @@ void Accelerometer::initValues()
   */
 void Accelerometer::calibrate(void)
 {
-    QFile file(kFileName);
-    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
-
     unsigned int iteration = 0;
+    qreal sampleX, sampleY, sampleZ;
 
-    QByteArray line;
-    QRegExp rx("([0-9-]+) ([0-9-]+) ([0-9-]+)");
+    calibrateDialog = new CalibrateDialog();
+    calibrateDialog->show();
+    calibrateDialog->resetProgressValue();
+    calibrateDialog->setMaxValue( kIterations + 1 );
 
     do {
-        // Read data, parse with regular expressions and process it
-        line = file.readLine();
-        rx.indexIn(line);
+        calibrateDialog->setProgressValue(iteration);
 
-        int sampleX = rx.cap(1).toInt();
-        int sampleY = rx.cap(2).toInt();
-        int sampleZ = rx.cap(3).toInt();
+        getAcceleration(sampleX, sampleY, sampleZ);
 
         calibrationX += sampleX; // Accumulate Samples
         calibrationY += sampleY; // for all axes.
         calibrationZ += sampleZ;
 
         iteration++;
-    } while(iteration!=1024);       // 1024 times
 
-    calibrationX = sstatex>>10;     // division by 1024
-    calibrationY = sstatey>>10;
-    calibrationZ = sstatez>>10;
+    } while(iteration != kIterations);        // kIterations times
+
+    calibrationX = calibrationX/kIterations;  // division by kIterations
+    calibrationY = calibrationY/kIterations;
+    calibrationZ = calibrationZ/kIterations;
 
-    file.close();
+    calibrateDialog->close();
 }
 
 /**
- * Stop measuring
+ * Smooths Accelerometer data by applying a low pass filter to data
  *
+ * @param x accelerometer's x-axis input
+ * @param y accelerometer's y-axis input
+ * @param z accelerometer's z-axis input
  */
-void Accelerometer::stop()
+void Accelerometer::smoothData(qreal &x, qreal &y, qreal &z)
 {
-    timer->stop();
+    x = (previousAccelerationX * (1 - kFilteringFactor)) + (x * kFilteringFactor);
+    y = (previousAccelerationY * (1 - kFilteringFactor)) + (y * kFilteringFactor);
+    z = (previousAccelerationZ * (1 - kFilteringFactor)) + (z * kFilteringFactor);
+
+    previousAccelerationX = x;
+    previousAccelerationY = y;
+    previousAccelerationZ = z;
 }
 
 /**
- * Set the sample rate of accelerometer
+ * Gets the raw acceleration data from accelerometer
  *
- * @param pSampleRate desired sample rate
+ * @param x accelerometer's x-axis input
+ * @param y accelerometer's y-axis input
+ * @param z accelerometer's z-axis input
  */
-void Accelerometer::setSampleRate(int pSampleRate)
-{
-    sampleRate = pSampleRate;
+void Accelerometer::getAcceleration(qreal &x, qreal &y, qreal &z)
+{
+    QDBusConnection connection(QDBusConnection::systemBus());
+    if (connection.isConnected()) {
+        QDBusInterface interface("com.nokia.mce", "/com/nokia/icd", QString(), connection);
+        QDBusPendingReply<QString, QString, QString, int, int, int> reply;
+        reply = interface.asyncCall("get_device_orientation");
+        reply.waitForFinished();
+        x = static_cast<qreal>(reply.argumentAt<3>()) / 1000;
+        y = static_cast<qreal>(reply.argumentAt<4>()) / 1000;
+        z = static_cast<qreal>(reply.argumentAt<5>()) / 1000;
+    }
 }
 
 /**
- * Get the sample rate of accelerometer
+ * Get the x calibration component
  *
- * @return sampleRate the sample rate of the accelerometer in milliseconds
+ * @return calibrationX x calibration component
  */
-int Accelerometer::getSampleRate()
-{
-    return sampleRate;
-}
-
-qreal Accelerometer::getCurrentAcceleration()
-{
-    return currentAcceleration;
-}
-
-qreal Accelerometer::getPreviousTotalAcceleration()
-{
-    return previousAcceleration;
-}
-
-qreal Accelerometer::getTotalAcceleration()
-{
-    return totalAcceleration;
-}
-
-qreal Accelerometer::getDistanceTraveled()
+qreal Accelerometer::getCalibrationX()
 {
-    return distanceTraveled;
-}
-
-qreal Accelerometer::getLastDistanceTraveled()
-{
-    return lastDistanceTraveled;
-}
-
-qreal Accelerometer::getAverageSpeed()
-{
-    return averageSpeed;
-}
-
-qreal Accelerometer::getTrueAccelerationX()
-{
-    return trueAccelerationX;
-}
-
-qreal Accelerometer::getTrueAccelerationY()
-{
-    return trueAccelerationY;
-}
-
-qreal Accelerometer::getTrueAccelerationZ()
-{
-    return trueAccelerationZ;
-}
-
-qreal Accelerometer::getPreviousSpeed()
-{
-    return previousSpeed;
-}
-
-qreal Accelerometer::getCurrentSpeed()
-{
-    return currentSpeed;
-}
-
-qreal Accelerometer::getIntervalTime()
-{
-    return intervalTime;
+    return calibrationX;
 }
 
 /**
- * Processes Accelerometer data
- *
- * Opens the accelerometer value file for reading and reads and parses accelerometer values.
- * Forwards data to Calculate class for processing
+ * Get the y calibration component
  *
+ * @return calibrationY y calibration component
  */
-void Accelerometer::processData()
+qreal Accelerometer::getCalibrationY()
 {
-    QFile file(kFileName);
-    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
-
-    // Read data, parse with regular expressions and process it
-    QByteArray line = file.readLine();
-    QRegExp rx("([0-9-]+) ([0-9-]+) ([0-9-]+)");
-    rx.indexIn(line);
-
-    smoothData(rx.cap(1).toInt(), rx.cap(2).toInt(), rx.cap(3).toInt());
-
-    // Apply calibration
-    trueAccelerationX = accelerationX - calibrationX;
-    trueAccelerationY = accelerationY - calibrationY;
-    trueAccelerationZ = accelerationZ - calibrationZ;
-
-    // Discrimination window for acceleration values
-    if (trueAccelerationX <= 30 && trueAccelerationX >= -30) { trueAccelerationX = 0; }
-    if (trueAccelerationY <= 30 && trueAccelerationY >= -30) { trueAccelerationY = 0; }
-    if (trueAccelerationZ <= 30 && trueAccelerationZ >= -30) { trueAccelerationZ = 0; }
-
-    trueAccelerationX = (accelerationX - previousAccelerationX) / 1000 * kGravity;
-    trueAccelerationY = (accelerationY - previousAccelerationY) / 1000 * kGravity;
-    trueAccelerationZ = (accelerationZ - previousAccelerationZ) / 1000 * kGravity;
-
-    previousAccelerationX = accelerationX;
-    previousAccelerationY = accelerationY;
-    previousAccelerationZ = accelerationZ;
-
-    currentAcceleration = sqrt(trueAccelerationX * trueAccelerationX +
-                               trueAccelerationY * trueAccelerationY +
-                               trueAccelerationZ * trueAccelerationZ );
-
-    totalAcceleration = currentAcceleration - previousAcceleration;
-    previousAcceleration = currentAcceleration;
-
-    // Measure time interval
-    intervalTime = now.restart(); // millisecs to secs
-    intervalTime = intervalTime/1000;
-    totalTime = totalTime + intervalTime;
-
-    // Filter out acceleration caused by noise.
-    if (fabs(currentAcceleration) < 0.09) {
-        return;
-    }
-
-    // Using calculate class to calculate velocity and distance etc.
-    calculate->CalculateParameters(currentAcceleration,intervalTime );
-
-    currentSpeed = calculate->CurrentSpeed();
-    distanceTraveled = calculate->DistanceTraveled();
-
-    file.close();
+    return calibrationY;
 }
 
 /**
- * Smooths Accelerometer data
+ * Get the z calibration component
  *
- * @param x accelerometer's x-axis input
- * @param y accelerometer's y-axis input
- * @param z accelerometer's z-axis input
+ * @return calibrationZ z calibration component
  */
-void Accelerometer::smoothData(qreal x, qreal y, qreal z)
+qreal Accelerometer::getCalibrationZ()
 {
-    accelerationX = x;
-    accelerationY = y;
-    accelerationZ = z;
-    if(sampleIndex>0) {
-        accelerationX = previousAccelerationX + (accelerationX-previousAccelerationX) * kFilteringFactor;
-        accelerationY = previousAccelerationY + (accelerationY-previousAccelerationY) * kFilteringFactor;
-        accelerationZ = previousAccelerationZ + (accelerationZ-previousAccelerationZ) * kFilteringFactor;
-    }
-    sampleIndex++;
+    return calibrationZ;
 }