-#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
*/
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;
}
/**
*/
Accelerometer::~Accelerometer()
{
-}
-
-/**
- * Start measuring
- *
- */
-void Accelerometer::start()
-{
- initValues();
- calibrate();
- timer->start(sampleRate);
- now.restart();
+ if(calibrateDialog)
+ delete calibrateDialog;
}
/**
*/
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;
}
/**
void Accelerometer::calibrate(void)
{
unsigned int iteration = 0;
+ qreal sampleX, sampleY, sampleZ;
- do {
- // Opening the file must be done inside the loop
- // or else the values obtained from file.readLine();
- // will be empty for all but the first iteration
- QFile file(kFileName);
- if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
- {
- return;
- }
+ calibrateDialog = new CalibrateDialog();
+ calibrateDialog->show();
+ calibrateDialog->resetProgressValue();
+ calibrateDialog->setMaxValue( kIterations + 1 );
- QByteArray line;
- QRegExp rx("([0-9-]+) ([0-9-]+) ([0-9-]+)");
-
- // Read data, parse with regular expressions and process it
- line = file.readLine();
- rx.indexIn(line);
+ do {
+ 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 = calibrationX + sampleX; // Accumulate Samples
- calibrationY = calibrationY + sampleY; // for all axes.
- calibrationZ = calibrationZ + sampleZ;
+ calibrationX += sampleX; // Accumulate Samples
+ calibrationY += sampleY; // for all axes.
+ calibrationZ += sampleZ;
iteration++;
- file.close();
- } while(iteration != 1024); // 1024 times
+ } while(iteration != kIterations); // kIterations times
- calibrationX = calibrationX>>10; // division by 1024
- calibrationY = calibrationY>>10;
- calibrationZ = calibrationZ>>10;
+ calibrationX = calibrationX/kIterations; // division by kIterations
+ calibrationY = calibrationY/kIterations;
+ calibrationZ = calibrationZ/kIterations;
+
+ 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()
+qreal Accelerometer::getCalibrationX()
{
- return sampleRate;
-}
-
-qreal Accelerometer::getCurrentAcceleration()
-{
- return currentAcceleration;
-}
-
-qreal Accelerometer::getPreviousTotalAcceleration()
-{
- return previousAcceleration;
-}
-
-qreal Accelerometer::getTotalAcceleration()
-{
- return totalAcceleration;
-}
-
-qreal Accelerometer::getDistanceTraveled()
-{
- 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;
-}
-
-qreal Accelerometer::getTotalTime()
-{
- return totalTime;
+ 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->getCurrentSpeed();
- distanceTraveled = calculate->getDistanceTraveled();
-
- 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;
}