Acceleration dialogs added.
authorJukka Kurttila <jukka.kurttila@fudeco.com>
Tue, 30 Mar 2010 10:56:29 +0000 (13:56 +0300)
committerJukka Kurttila <jukka.kurttila@fudeco.com>
Tue, 30 Mar 2010 10:56:29 +0000 (13:56 +0300)
15 files changed:
Client/accelerationstart.cpp [new file with mode: 0644]
Client/accelerationstart.h [new file with mode: 0644]
Client/accelerationstartdialog.ui [new file with mode: 0644]
Client/accelerometer.cpp [new file with mode: 0644]
Client/accelerometer.h [new file with mode: 0644]
Client/accrealtimedialog.cpp [new file with mode: 0644]
Client/accrealtimedialog.h [new file with mode: 0644]
Client/accrealtimedialog.ui [new file with mode: 0644]
Client/calculate.cpp [new file with mode: 0644]
Client/calculate.h [new file with mode: 0644]
Client/mainwindow.cpp
Client/mainwindow.h
Client/movingaverage.cpp [new file with mode: 0644]
Client/movingaverage.h [new file with mode: 0644]
Client/speedfreak.pro

diff --git a/Client/accelerationstart.cpp b/Client/accelerationstart.cpp
new file mode 100644 (file)
index 0000000..3da0070
--- /dev/null
@@ -0,0 +1,75 @@
+#include "accelerationstart.h"
+#include "ui_accelerationstartdialog.h"
+#include <QMessageBox>
+
+accelerationstart::accelerationstart(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::accelerationstart)
+{
+    ui->setupUi(this);
+    ui->buttonStart->setDisabled(true);
+    accRealTimeDialog = NULL;
+    stopMeasureSpeed = 0;
+
+    ui->categorComboBox->addItem("Select category");
+    //ui->categorComboBox->addItem("-");
+    ui->categorComboBox->addItem("0 - 20 km/h",20);
+    ui->categorComboBox->addItem("0 - 40 km/h");
+    ui->categorComboBox->addItem("0 - 100 km/h");
+}
+
+accelerationstart::~accelerationstart()
+{
+    delete ui;
+    if(accRealTimeDialog)
+        delete accRealTimeDialog;
+}
+
+void accelerationstart::changeEvent(QEvent *e)
+{
+    QDialog::changeEvent(e);
+    switch (e->type()) {
+    case QEvent::LanguageChange:
+        ui->retranslateUi(this);
+        break;
+    default:
+        break;
+    }
+}
+
+void accelerationstart::on_buttonCalib_clicked()
+{
+    if(accRealTimeDialog == NULL)
+        accRealTimeDialog = new AccRealTimeDialog(this);
+
+    accRealTimeDialog->Calibrate();
+
+    ui->buttonStart->setEnabled(true);
+}
+
+void accelerationstart::on_buttonStart_clicked()
+{
+    if( stopMeasureSpeed == 0 )
+    {
+        QMessageBox msgBox;
+        msgBox.setWindowTitle("Can not start measure!");
+        msgBox.setText("Select category first!");
+        msgBox.setDefaultButton(QMessageBox::Ok);
+        msgBox.exec();
+        return;
+    }
+    accRealTimeDialog->SetStopMeasureSpeed( stopMeasureSpeed );
+    accRealTimeDialog->startAccelerationMeasure();
+    accRealTimeDialog->show();
+}
+
+void accelerationstart::on_categorComboBox_currentIndexChanged( int index )
+{
+    stopMeasureSpeed = 0;
+    if( index == 1 )
+        stopMeasureSpeed = 20;
+    else if( index == 2 )
+        stopMeasureSpeed = 40;
+    else if( index == 3 )
+        stopMeasureSpeed = 100;
+}
diff --git a/Client/accelerationstart.h b/Client/accelerationstart.h
new file mode 100644 (file)
index 0000000..ecd2406
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef ACCELERATIONSTART_H
+#define ACCELERATIONSTART_H
+
+#include <QDialog>
+#include "accrealtimedialog.h"
+
+namespace Ui {
+    class accelerationstart;
+}
+
+class accelerationstart : public QDialog {
+    Q_OBJECT
+public:
+    accelerationstart(QWidget *parent = 0);
+    ~accelerationstart();
+
+protected:
+    void changeEvent(QEvent *e);
+
+private:
+    Ui::accelerationstart *ui;
+    AccRealTimeDialog* accRealTimeDialog;
+    double stopMeasureSpeed;
+
+private slots:
+    void on_categorComboBox_currentIndexChanged(int index);
+    void on_buttonStart_clicked();
+    void on_buttonCalib_clicked();
+};
+
+#endif // ACCELERATIONSTART_H
diff --git a/Client/accelerationstartdialog.ui b/Client/accelerationstartdialog.ui
new file mode 100644 (file)
index 0000000..76af4e5
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>accelerationstart</class>
+ <widget class="QDialog" name="accelerationstart">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>480</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Start acceleration measure</string>
+  </property>
+  <widget class="QComboBox" name="categorComboBox">
+   <property name="geometry">
+    <rect>
+     <x>50</x>
+     <y>140</y>
+     <width>221</width>
+     <height>51</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="buttonCalib">
+   <property name="geometry">
+    <rect>
+     <x>310</x>
+     <y>130</y>
+     <width>171</width>
+     <height>71</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Calibrate</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="buttonStart">
+   <property name="geometry">
+    <rect>
+     <x>520</x>
+     <y>130</y>
+     <width>181</width>
+     <height>71</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Start</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Client/accelerometer.cpp b/Client/accelerometer.cpp
new file mode 100644 (file)
index 0000000..0495135
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * 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 "accelerometer.h"
+
+#include <QDBusConnection>
+#include <QDBusInterface>
+#include <QDBusPendingReply>
+
+#define kFilteringFactor 0.2
+
+/**
+ * Default constructor for Accelerometer class
+ *
+ */
+Accelerometer::Accelerometer()
+{
+    initValues();
+}
+
+/**
+ * Default destructor for Accelerometer class
+ *
+ */
+Accelerometer::~Accelerometer()
+{
+}
+
+/**
+ * Init class members
+ *
+ */
+void Accelerometer::initValues()
+{
+    previousAccelerationX = 0;
+    previousAccelerationY = 0;
+    previousAccelerationZ = 0;
+    calibrationX = 0;
+    calibrationY = 0;
+    calibrationZ = 0;
+}
+
+/**
+  * Calibrate. Purpose of this function is to calibrate
+  * accelerometer when stationary.
+  *
+  */
+void Accelerometer::calibrate(void)
+{
+    unsigned int iteration = 0;
+    qreal sampleX, sampleY, sampleZ;
+
+    do {
+
+        getAcceleration(sampleX, sampleY, sampleZ);
+
+        calibrationX += sampleX; // Accumulate Samples
+        calibrationY += sampleY; // for all axes.
+        calibrationZ += sampleZ;
+
+        iteration++;
+
+    } while(iteration != 1024);        // 1024 times
+
+    calibrationX = calibrationX/1024;  // division by 1024
+    calibrationY = calibrationY/1024;
+    calibrationZ = calibrationZ/1024;
+}
+
+/**
+ * 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::smoothData(qreal &x, qreal &y, qreal &z)
+{
+    x = (previousAccelerationX * (1 - kFilteringFactor)) + (x * kFilteringFactor);
+    y = (previousAccelerationY * (1 - kFilteringFactor)) + (y * kFilteringFactor);
+    z = (previousAccelerationZ * (1 - kFilteringFactor)) + (z * kFilteringFactor);
+
+    previousAccelerationX = x;
+    previousAccelerationY = y;
+    previousAccelerationZ = z;
+}
+
+/**
+ * Gets the raw acceleration data from accelerometer
+ *
+ * @param x accelerometer's x-axis input
+ * @param y accelerometer's y-axis input
+ * @param z accelerometer's z-axis input
+ */
+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 x calibration component
+ *
+ * @return calibrationX x calibration component
+ */
+qreal Accelerometer::getCalibrationX()
+{
+    return calibrationX;
+}
+
+/**
+ * Get the y calibration component
+ *
+ * @return calibrationY y calibration component
+ */
+qreal Accelerometer::getCalibrationY()
+{
+    return calibrationY;
+}
+
+/**
+ * Get the z calibration component
+ *
+ * @return calibrationZ z calibration component
+ */
+qreal Accelerometer::getCalibrationZ()
+{
+    return calibrationZ;
+}
diff --git a/Client/accelerometer.h b/Client/accelerometer.h
new file mode 100644 (file)
index 0000000..24063cd
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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
+ */
+
+#ifndef ACCELEROMETER_H
+#define ACCELEROMETER_H
+
+#include <QObject>
+
+#include "calculate.h"
+
+class Accelerometer : public QObject
+{
+    Q_OBJECT
+public:
+    Accelerometer();
+    ~Accelerometer();
+
+    void getAcceleration(qreal &x, qreal &y, qreal &z);
+    void smoothData(qreal &x, qreal &y, qreal &z);
+    void calibrate();
+    void initValues();
+
+    qreal getCalibrationX();
+    qreal getCalibrationY();
+    qreal getCalibrationZ();
+
+private:
+    qreal previousAccelerationX, previousAccelerationY, previousAccelerationZ;
+    qreal calibrationX, calibrationY, calibrationZ;
+};
+
+#endif // ACCELEROMETER_H
diff --git a/Client/accrealtimedialog.cpp b/Client/accrealtimedialog.cpp
new file mode 100644 (file)
index 0000000..dc58627
--- /dev/null
@@ -0,0 +1,172 @@
+#include "accrealtimedialog.h"
+#include "ui_accrealtimedialog.h"
+#include <math.h>
+
+AccRealTimeDialog::AccRealTimeDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::AccRealTimeDialog)
+{
+    ui->setupUi(this);
+
+    accelerometer = new Accelerometer();
+    movingAverageZ = new MovingAverage(10);
+    calculate = new Calculate();
+    accelerationStartThreshold = 0.1;
+
+    accelerometerTimer = new QTimer(this);
+    connect(accelerometerTimer, SIGNAL(timeout()), this, SLOT(readAccelerometerData()));
+    isNewRun = true;
+    updateScreenCounter = 0;
+    resetAccelerometerMeasurements();
+
+    //Load image
+    QPixmap pixMap("back.png",0,Qt::AutoColor);
+    ui->pictureLabel->setPixmap(pixMap);
+}
+
+AccRealTimeDialog::~AccRealTimeDialog()
+{
+    delete ui;
+    delete accelerometer;
+    delete accelerometerTimer;
+    delete calculate;
+    delete movingAverageZ;
+}
+
+void AccRealTimeDialog::changeEvent(QEvent *e)
+{
+    QDialog::changeEvent(e);
+    switch (e->type()) {
+    case QEvent::LanguageChange:
+        ui->retranslateUi(this);
+        break;
+    default:
+        break;
+    }
+}
+/**
+  *This function is called to read (and process) data from the accelerometer
+  */
+void AccRealTimeDialog::readAccelerometerData()
+{
+    QString s;
+    double changeInAcceleration = 0;
+    qreal x, y, z;
+
+    accelerometer->getAcceleration(x, y, z);
+
+    //  keep the following line as close to the SetKinematicsProperties method as possible
+    currentTime = elapsedTime.elapsed();
+
+    //accelerometer->smoothData(x, y, z);
+
+    //Calculate average
+    movingAverageZ->Enqueue(z);
+    z = movingAverageZ->Average();
+
+    // Apply calibration
+    x -= accelerometer->getCalibrationX();
+    y -= accelerometer->getCalibrationY();
+    z -= accelerometer->getCalibrationZ();
+
+    QString str = QString("acc x: " + QString::number(x) + "\n" +
+                          "acc y: " + QString::number(y) + "\n" +
+                          "acc z: " + QString::number(z) + "\n");
+
+    currentAcceleration = z;//sqrt(x*x + y*y + z*z);
+    changeInAcceleration = currentAcceleration;
+
+    if (((fabs(changeInAcceleration) <= accelerationStartThreshold)
+                && !vehicleStartedMoving))
+    {
+        return;
+    }
+    else if(!vehicleStartedMoving)
+    {
+        vehicleStartedMoving = true;
+        elapsedTime.start();
+        previousTime = 0;
+        currentTime = 0;
+    }
+
+    calculate->calculateParameters(changeInAcceleration, (currentTime - previousTime)/1000);
+    previousTime = currentTime;
+
+    //s.sprintf("%.2f", changeInAcceleration);
+    //currentAccelerationString = s;
+
+    speed = 0;
+    speed = calculate->getCurrentSpeed();
+    //Convert to km/h
+    speed = speed*3.6;
+    s.sprintf("%.1f", speed);
+    currentSpeed = s;
+
+    //s.sprintf("%.2f", calculate->getDistanceTraveled());
+    //distanceTraveled = s;
+
+    // TODO
+    //distanceTraveled;
+    //horsepower;
+
+    time = calculate->getTotalTime();
+
+    s.sprintf("%.2f", time);
+    totalTime = s;
+
+    //str.append("ca: " + currentAccelerationString + " G\n" );
+    //str.append("cspeed: " + currentSpeed + " km/h \n" );
+    //str.append("dist: " + distanceTraveled + " m \n" );
+    //str.append("time: " + totalTime + " s \n" );
+
+    if( updateScreenCounter == 5 )
+    {
+        ui->realSpeedLabel->setText( currentSpeed );
+        ui->timeLabel->setText( totalTime );
+        updateScreenCounter = 0;
+    }
+    updateScreenCounter++;
+
+    //Open result dialog if target speed reached
+    if( speed > stopMeasureSpeed )
+    {
+        this->accelerometerTimer->stop();
+    }
+}
+
+/**
+  * Resets Accelerometer measurement variables
+  */
+void AccRealTimeDialog::resetAccelerometerMeasurements()
+{
+    speed = 0;
+    currentAcceleration = 0;
+    currentSpeed = "";
+    currentTime = 0;
+    isNewRun = true;
+    previousTime = 0;
+    elapsedTime.start();
+    totalTime = "";
+    calculate->reset();
+    vehicleStartedMoving = false;
+    stopMeasureSpeed = 0;
+}
+void AccRealTimeDialog::Calibrate()
+{
+    accelerometer->calibrate();
+}
+
+void AccRealTimeDialog::on_buttonAbort_clicked()
+{
+    accelerometerTimer->stop();
+    resetAccelerometerMeasurements();
+    this->close();
+}
+void AccRealTimeDialog::startAccelerationMeasure()
+{
+    accelerometerTimer->start(40);
+}
+void AccRealTimeDialog::SetStopMeasureSpeed(double speed)
+{
+    stopMeasureSpeed = speed;
+}
diff --git a/Client/accrealtimedialog.h b/Client/accrealtimedialog.h
new file mode 100644 (file)
index 0000000..b389818
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef ACCREALTIMEDIALOG_H
+#define ACCREALTIMEDIALOG_H
+
+#include <QDialog>
+#include <QTimer>
+#include "accelerometer.h"
+#include "movingaverage.h"
+
+namespace Ui {
+    class AccRealTimeDialog;
+}
+
+class AccRealTimeDialog : public QDialog {
+    Q_OBJECT
+public:
+    AccRealTimeDialog(QWidget *parent = 0);
+    ~AccRealTimeDialog();
+    void Calibrate();
+    void startAccelerationMeasure();
+    void SetStopMeasureSpeed(double speed);
+
+protected:
+    void changeEvent(QEvent *e);
+
+private slots:
+    void on_buttonAbort_clicked();
+    void readAccelerometerData();
+
+private:
+    Ui::AccRealTimeDialog *ui;
+    void resetAccelerometerMeasurements();
+
+    QTimer *accelerometerTimer;
+    QTime elapsedTime;
+    Accelerometer* accelerometer;
+    Calculate *calculate;
+    MovingAverage* movingAverageZ;
+
+    int updateScreenCounter;
+    double accelerationStartThreshold;
+    double currentAcceleration;
+    double currentTime;
+    double previousTime;
+    double time;
+    double speed;
+    double stopMeasureSpeed;
+    bool vehicleStartedMoving;
+    bool isNewRun;
+
+    QString currentSpeed;
+    QString totalTime;
+};
+
+#endif // ACCREALTIMEDIALOG_H
diff --git a/Client/accrealtimedialog.ui b/Client/accrealtimedialog.ui
new file mode 100644 (file)
index 0000000..d63e753
--- /dev/null
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AccRealTimeDialog</class>
+ <widget class="QDialog" name="AccRealTimeDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>480</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Acceleration measure in progress...</string>
+  </property>
+  <widget class="QWidget" name="horizontalLayoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>450</x>
+     <y>40</y>
+     <width>211</width>
+     <height>80</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,2,0">
+    <property name="spacing">
+     <number>12</number>
+    </property>
+    <item>
+     <widget class="QLabel" name="speedLabel">
+      <property name="text">
+       <string>Speed:</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QLabel" name="realSpeedLabel">
+      <property name="text">
+       <string>0</string>
+      </property>
+      <property name="alignment">
+       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QLabel" name="kmhLabel">
+      <property name="text">
+       <string>km/h</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QWidget" name="horizontalLayoutWidget_2">
+   <property name="geometry">
+    <rect>
+     <x>450</x>
+     <y>140</y>
+     <width>211</width>
+     <height>80</height>
+    </rect>
+   </property>
+   <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,2,1">
+    <property name="spacing">
+     <number>12</number>
+    </property>
+    <item>
+     <widget class="QLabel" name="timeTextLabel">
+      <property name="text">
+       <string>Time:</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QLabel" name="timeLabel">
+      <property name="text">
+       <string>0</string>
+      </property>
+      <property name="alignment">
+       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QLabel" name="secondsLabel">
+      <property name="text">
+       <string>s</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QPushButton" name="buttonAbort">
+   <property name="geometry">
+    <rect>
+     <x>450</x>
+     <y>240</y>
+     <width>211</width>
+     <height>51</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Abort</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="pictureLabel">
+   <property name="geometry">
+    <rect>
+     <x>100</x>
+     <y>50</y>
+     <width>256</width>
+     <height>256</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+   <property name="pixmap">
+    <pixmap resource="graphics.qrc">:/new/prefix1/Graphics/Speedometer .png</pixmap>
+   </property>
+   <property name="scaledContents">
+    <bool>true</bool>
+   </property>
+  </widget>
+ </widget>
+ <resources>
+  <include location="graphics.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/Client/calculate.cpp b/Client/calculate.cpp
new file mode 100644 (file)
index 0000000..fb56f12
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * 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>
+
+#include <QFile>
+#include <QString>
+#include <QTimer>
+#include <QRegExp>
+
+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;
+
+const double carFrontalArea = 1.5;
+const double dragCoefficient = 0.31;
+const int carWeight = 850;
+
+Calculate::Calculate()
+{
+    this->reset();
+}
+
+Calculate::~Calculate()
+{
+
+}
+
+void Calculate::reset()
+{
+    averageSpeed = 0;
+    averagePower = 0;
+    peakPower = 0;
+    currentPower = 0;
+    currentSpeed = 0;
+    maxSpeed = 0;
+    distanceTraveled = 0;
+    lastAcceleration = 0;
+    lastDistance = 0;
+    lastSpeed = 0;
+    numOfIterations = 0;
+    totalTime = 0;
+    count = 0;
+
+    if(speedCheckPoints.count() == 0)
+    {
+        speedCheckPoints.append(10);
+        speedCheckPoints.append(20);
+        speedCheckPoints.append(30);
+        speedCheckPoints.append(40);
+        speedCheckPoints.append(50);
+        speedCheckPoints.append(60);
+        speedCheckPoints.append(70);
+        speedCheckPoints.append(80);
+        speedCheckPoints.append(90);
+        speedCheckPoints.append(100);
+    }
+
+    checkPointCounter = 0;
+    checkPoint = speedCheckPoints[checkPointCounter];
+
+}
+
+
+/**
+  * 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));
+
+    // Update maximum speed
+    if (currentSpeed > maxSpeed)
+        maxSpeed = currentSpeed;
+
+    // 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--;
+    }
+
+    if( (checkPoint > 0) && (currentSpeed*3.6 > checkPoint) )
+    {
+        //Update checkPoint
+        if( checkPointCounter <= speedCheckPoints.count() )
+        {
+            //Save time
+            valuesMap.insert( checkPoint, totalTime );
+            if( checkPointCounter < speedCheckPoints.count() )
+            {
+                checkPoint = speedCheckPoints[checkPointCounter];
+            }
+            else
+            {
+                checkPoint = 0;
+            }
+            checkPointCounter++;
+        }
+    }
+
+    // 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 25, we assume that velocity is zero
+    if (count >= 25)
+    {
+        currentSpeed=0;
+    }
+}
+
+// Getters and setters
+
+double Calculate::getAverageSpeed()
+{
+    return averageSpeed;
+}
+
+void Calculate::setAverageSpeed(double value)
+{
+    averageSpeed = value;
+}
+
+double Calculate::getCurrentSpeed()
+{
+    return currentSpeed;
+}
+
+void Calculate::setCurrentSpeed(double value)
+{
+    currentSpeed = value;
+}
+
+double Calculate::getDistanceTraveled()
+{
+    return distanceTraveled;
+}
+
+void Calculate::setDistanceTraveled(double value)
+{
+    distanceTraveled = value;
+}
+
+double Calculate::getLastAcceleration()
+{
+    return lastAcceleration;
+}
+
+void Calculate::setLastAcceleration(double value)
+{
+    lastAcceleration = value;
+}
+
+double Calculate::getLastDistance()
+{
+    return lastDistance;
+}
+
+void Calculate::setLastDistance(double value)
+{
+    lastDistance = value;
+}
+
+double Calculate::getLastSpeed()
+{
+    return lastSpeed;
+}
+
+void Calculate::setLastSpeed(double value)
+{
+    lastSpeed = value;
+}
+
+long Calculate::getNumOfIterations()
+{
+    return numOfIterations;
+}
+
+void Calculate::setNumOfIterations(long value)
+{
+    numOfIterations = value;
+}
+
+double Calculate::getTotalTime()
+{
+    return totalTime;
+}
+
+void Calculate::setTotalTime(double value)
+{
+    totalTime = value;
+}
+
+double Calculate::getCurrentPower()
+{
+    return currentPower;
+}
+
+void Calculate::setCurrentPower(double value)
+{
+    currentPower = value;
+}
+
+double Calculate::getPeakPower()
+{
+    return peakPower;
+}
+
+void Calculate::setPeakPower(double value)
+{
+    peakPower = value;
+}
+
+double Calculate::getAveragePower()
+{
+    if (numOfIterations > 0)
+    {
+        return (averagePower/numOfIterations);
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+void Calculate::setAveragePower(double value)
+{
+    averagePower = value;
+}
+
+double Calculate::getMaxSpeed()
+{
+    return maxSpeed;
+}
+
+void Calculate::setMaxSpeed(double value)
+{
+    maxSpeed = value;
+}
+
diff --git a/Client/calculate.h b/Client/calculate.h
new file mode 100644 (file)
index 0000000..bc3f81d
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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
+ */
+
+#ifndef CALCULATE_H
+#define CALCULATE_H
+
+#include <QObject>
+#include <QTime>
+#include <QList>
+#include <QMap>
+
+class Calculate : public QObject
+{
+    Q_OBJECT
+
+public:
+    Calculate();
+    ~Calculate();
+
+    void reset();
+    void calculateParameters(double currentAcceleration, double seconds);
+    void accelStoppedCheck(double currentAcceleration);
+
+    double getAverageSpeed();
+    void setAverageSpeed(double value);
+
+    double getCurrentSpeed();
+    void setCurrentSpeed(double value);
+
+    double getDistanceTraveled();
+    void setDistanceTraveled(double value);
+
+    double getLastAcceleration();
+    void setLastAcceleration(double value);
+
+    double getLastCheckpoint();
+    void setLastCheckpoint(double value);
+
+    double getLastDistance();
+    void setLastDistance(double value);
+
+    double getLastSpeed();
+    void setLastSpeed(double value);
+
+    long getNumOfIterations();
+    void setNumOfIterations(long value);
+
+    double getTotalTime();
+    void setTotalTime(double value);
+
+    double getCurrentPower();
+    void setCurrentPower(double value);
+
+    double getPeakPower();
+    void setPeakPower(double value);
+
+    double getAveragePower();
+    void setAveragePower(double value);
+
+    double getMaxSpeed();
+    void setMaxSpeed(double value);
+
+private:
+    double averageSpeed;
+    double currentSpeed;
+    double maxSpeed;
+    double distanceTraveled;
+    double lastAcceleration;
+    double lastDistance;
+    double lastSpeed;
+    double checkPoint;
+    long numOfIterations;
+    double totalTime;
+    int count;
+    int checkPointCounter;
+    double peakPower;
+    double currentPower;
+    double averagePower;
+    QList<int> speedCheckPoints;
+public:
+    QMap<int,double> valuesMap;
+
+signals:
+    void checkPointReached(double totalTime, double currentSpeed);
+
+};
+
+#endif // CALCULATE_H
index 8a46249..6ea222a 100644 (file)
@@ -26,6 +26,7 @@ MainWindow::MainWindow(QWidget *parent) :
     creditsDialog = new CreditsDialog;
     routeSaveDialog = new RouteSaveDialog;
     settingsDialog = new SettingsDialog;
+    accstart = NULL;
 
     welcomeDialog = new WelcomeDialog;
     welcomeDialog->show();
@@ -36,6 +37,9 @@ MainWindow::~MainWindow()
     delete ui;
 
     delete routeSaveDialog;
+
+    if(!accstart)
+        delete accstart;
 }
 
 void MainWindow::changeEvent(QEvent *e)
@@ -69,3 +73,10 @@ void MainWindow::on_pushButtonSettings_clicked()
 {
     settingsDialog->show();
 }
+
+void MainWindow::on_pushButtonAccelerate_clicked()
+{
+    if(!accstart)
+        accstart = new accelerationstart(this);
+    accstart->show();
+}
index f822184..14ab094 100644 (file)
@@ -14,6 +14,7 @@
 #include "routesavedialog.h"
 #include "welcomedialog.h"
 #include "settingsdialog.h"
+#include "accelerationstart.h"
 
 namespace Ui {
     class MainWindow;
@@ -29,6 +30,7 @@ public:
     RouteSaveDialog *routeSaveDialog;
     WelcomeDialog *welcomeDialog;
     SettingsDialog *settingsDialog;
+    accelerationstart* accstart;
 
 protected:
     void changeEvent(QEvent *e);
@@ -37,6 +39,7 @@ private:
     Ui::MainWindow *ui;
 
 private slots:
+    void on_pushButtonAccelerate_clicked();
     void on_pushButtonSettings_clicked();
     void on_pushButtonRoute_clicked();
     void on_pushButtonCredits_clicked();
diff --git a/Client/movingaverage.cpp b/Client/movingaverage.cpp
new file mode 100644 (file)
index 0000000..645f34a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Class for moving average of acceleration data.
+ *
+ * @author      Kai Rasilainen
+ * @copyright   (c) 2010 Speed Freak team
+ * @license     http://opensource.org/licenses/gpl-license.php GNU Public License
+ */
+
+#include "movingaverage.h"
+#include <QList>
+
+MovingAverage::MovingAverage(int sizeLimit)
+{
+    SizeLimit = sizeLimit;
+}
+
+double MovingAverage::Average()
+{
+    double sum = 0;
+
+    if (queue.count() == 0)
+        return 0;
+
+    QList<double> temp = queue;
+    foreach (double value, temp)
+    {
+        sum += value;
+    }
+
+    return sum / queue.count();
+}
+
+void MovingAverage::Resize(int sizeLimit)
+{
+    SizeLimit = sizeLimit;
+    while (queue.count() > SizeLimit)
+    {
+        queue.dequeue();
+    }
+}
+
+void MovingAverage::Enqueue(double item)
+{
+    queue.enqueue(item);
+    if (queue.count() > SizeLimit)
+        queue.dequeue();
+}
+
+
diff --git a/Client/movingaverage.h b/Client/movingaverage.h
new file mode 100644 (file)
index 0000000..53962fb
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  Class for moving average of acceleration data.
+ *
+ * @author      Kai Rasilainen
+ * @copyright   (c) 2010 Speed Freak team
+ * @license     http://opensource.org/licenses/gpl-license.php GNU Public License
+ */
+
+#ifndef MOVINGAVERAGE_H
+#define MOVINGAVERAGE_H
+
+#include <QQueue>
+
+class MovingAverage
+{
+
+public:
+    MovingAverage(int sizeLimit);
+
+    double Average();
+    void Resize(int sizeLimit);
+    void Enqueue(double item);
+
+private:
+    int SizeLimit;
+    QQueue<double> queue;
+};
+
+#endif // MOVINGAVERAGE_H
index cb18f04..1695f81 100644 (file)
@@ -1,6 +1,7 @@
 # -------------------------------------------------
 # Project created by QtCreator 2010-03-29T09:21:42
 # -------------------------------------------------
+QT += dbus
 TARGET = speedfreak
 TEMPLATE = app
 SOURCES += main.cpp \
@@ -12,7 +13,12 @@ SOURCES += main.cpp \
     usersettings.cpp \
     resultdialog.cpp \
     instructionsdialog.cpp \
-    settingsdialog.cpp
+    settingsdialog.cpp \
+    accelerationstart.cpp \
+    accrealtimedialog.cpp \
+    accelerometer.cpp \
+    movingaverage.cpp \
+    calculate.cpp
 HEADERS += mainwindow.h \
     creditsdialog.h \
     routedialog.h \
@@ -21,7 +27,12 @@ HEADERS += mainwindow.h \
     usersettings.h \
     resultdialog.h \
     instructionsdialog.h \
-    settingsdialog.h
+    settingsdialog.h \
+    accelerationstart.h \
+    accrealtimedialog.h \
+    accelerometer.h \
+    movingaverage.h \
+    calculate.h
 FORMS += mainwindow.ui \
     creditsdialog.ui \
     routedialog.ui \
@@ -29,5 +40,7 @@ FORMS += mainwindow.ui \
     welcomedialog.ui \
     resultdialog.ui \
     instructionsdialog.ui \
-    settingsdialog.ui
+    settingsdialog.ui \
+    accelerationstartdialog.ui \
+    accrealtimedialog.ui
 RESOURCES += graphics.qrc