/*
* Calculate class to process accelerometer data
*
- * @author Kai Rasilainen
+ * @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;
+
+const double carFrontalArea = 1.5;
+const double dragCoefficient = 0.31;
+const int carWeight = 850;
Calculate::Calculate()
{
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: params like horsepower.
+ */
+void Calculate::calculateParameters(double currentAcceleration, double seconds)
+{
+ double force, power1, power2;
+ 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 25, we assume that velocity is zero
+ if (count >= 25)
+ {
+ currentSpeed=0;
+ }
}
// Getters and setters
{
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)
-{
- 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);
-
- // 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;
- }
-}
-
-
/*
* Calculate class to process accelerometer data
*
- * @author Kai Rasilainen
+ * @author Kai Rasilainen
* @copyright (c) 2010 Speed Freak team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/
#include <QObject>
#include <QTime>
+#include <QList>
class Calculate : public QObject
{
long numOfIterations;
double totalTime;
int count;
+ double peakPower;
+ double currentPower;
+ double averagePower;
+ QList<int> speedCheckPoints;
+
+signals:
+ void checkPointReached(double totalTime, double currentSpeed);
};
+/*
+ * Loginwindow class to maintain username for user
+ *
+ * @author Olavi Pulkkinen <olavi.pulkkinen@fudeco.com>
+ * @author
+ * @copyright (c) 2010 Speed Freak team
+ * @license http://opensource.org/licenses/gpl-license.php GNU Public License
+ */
+
#include "loginwindow.h"
#include "ui_loginwindow.h"
#include <QMessageBox>
+/**
+ * LoginWindow class
+ *
+ * @author Olavi Pulkkinen <olavi.pulkkinen@fudeco.com>
+ * @copyright (c) 2010 Speed Freak team
+ * @license http://opensource.org/licenses/gpl-license.php GNU Public License
+ */
+
#ifndef LOGINWINDOW_H
#define LOGINWINDOW_H
+/*
+ * Registration class to registrate username for user
+ *
+ * @author Olavi Pulkkinen <olavi.pulkkinen@fudeco.com>
+ * @author
+ * @copyright (c) 2010 Speed Freak team
+ * @license http://opensource.org/licenses/gpl-license.php GNU Public License
+ */
+
#include "registration.h"
#include "ui_registration.h"
#include <QMessageBox>
+/**
+ * Registration class
+ *
+ * @author Olavi Pulkkinen <olavi.pulkkinen@fudeco.com>
+ * @copyright (c) 2010 Speed Freak team
+ * @license http://opensource.org/licenses/gpl-license.php GNU Public License
+ */
+
#ifndef REGISTRATION_H
#define REGISTRATION_H
<string>Cancel</string>
</property>
</widget>
- <widget class="QWidget" name="">
+ <widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>40</x>
<y>80</y>
<width>239</width>
- <height>74</height>
+ <height>95</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="2" column="0">
<widget class="QLabel" name="eMailLabel">
<property name="text">
- <string>Your Emai:l</string>
+ <string>Your Email:</string>
</property>
</widget>
</item>
<resources/>
<connections/>
</ui>
-
--- /dev/null
+API specifications for client-server communication
+==================================================
+
+
+General information
+===================
+
+This document will briefly describe API that is used in Speed Freak project.
+In this document client will be Maemo 5 application running on Nokia N900 device.
+Server will be PHP application running on api.speedfreak-app.com
+
+General technical information
+=============================
+
+XML will be used for encapsulating data sent to and received from server. XML will
+be sent using HTTP protocol as POST data. Once product is launched HTTP will be
+swapped in favor of HTTPS for additional security.
+
+All requests sent to server should satisfy following requirements:
+
+- Login and password supplied via HTTP basic authentication (not required for
+registration)
+- Post field xml should contain XML (not required in login request)
+- XML should be UTF8 encoded
+
+Server in return will respond with XML in body of the response if request was
+successful or with HTTP error code if there was problem processing the request.
+Successful requests return 200 HTTP status code.
+
+Here is the list of general errors that client might encounter:
+
+- 404: Request sent to incorrect URL
+- 500: General error during processing request
+- 403: Client has no privileges to access this resource
+- 400: Invalid request
+- 401: Failed to authenticate
+
+Registration process
+====================
+
+URL: /register
+
+Every single client should register before it can send own measurement results or
+fetch other's results. During registration client has to supply following information:
+
+- Login: This is 3-12 charecters long nickname that has to be unique
+- Password: 6-255 charectors long password
+- Email: email address that will be used for password recovery etc. Has to be unique.
+
+Below is example of XML that client might send to server to register an account:
+
+<?xml version="1.0" encoding="utf-8"?>
+<user>
+ <login>test827</login>
+ <password>thisisaveryinsecurepassword</password>
+ <email>test@example.com</email>
+</user>
+
+If registration is successful server will return 200 HTTP status code along with
+text "OK" in the response body. In other cases (invalid email, login exists etc)
+server will return HTTP error code 400 with error message in the body text.
+
+
+Login
+=====
+
+URL: /login
+
+Because communication with server has no state there is no need to login. Client
+might need to verify that credentials supplied by user are correct. In order to
+do that client can send a login request which will just verify that login and password
+are correct and user exists in database.
+
+When making a login request you don't have to supply XML, only basic authentication.
+If credentials are correct server will return "OK" along with HTTP status code 200.
+In any other case it will return 401 HTTP error code along with error description.
+
+
+Fetching results
+================
+
+URL: /results/category_name/limit
+
+Category: For example "acceleration-0-100", "top-speed" and so on
+Limit: This will tell server how many results you want to get back. Results are
+ordered by record position starting with highest record first.
+
+Both parameters are required.
+
+Below is example of what client might get back in return when sending following
+request: /results/acceleration-0-100/10
+
+<?xml version="1.0" encoding="utf-8"?>
+<results category="acceleration-0-100" unit="seconds" description="Acceleration from 0 to 100 km/h">
+ <result position="1" user="test928" date="12/1/2010" value="13" />
+ <result position="2" user="test922" date="15/1/2010" value="12" />
+ <result position="3" user="test92a" date="11/1/2010" value="11" />
+ <result position="4" user="test92s" date="15/2/2010" value="10" />
+ <result position="5" user="test92d" date="1/1/2010" value="9" />
+ <result position="6" user="test92f" date="31/1/2010" value="8" />
+ <result position="7" user="test92f" date="1/1/2010" value="7" />
+ <result position="8" user="test92g" date="2/1/2010" value="6" />
+ <result position="9" user="test92w" date="3/1/2010" value="5" />
+ <result position="10" user="test92a" date="17/1/2010" value="4" />
+</results>
+
+
+Sending results
+===============
+
+URL: /update/category_name
+
+Category: same as when fetching results
+
+In order to submit results to server client needs to send XML with measurement results to
+category that result belongs to. Below is example of XML:
+
+<?xml version="1.0" encoding="utf-8"?>
+<result value="14" unit="seconds" date="14/2/2010" />
+
+
+Logout
+======
+
+There is no need to logout as server is stateless, but client can mimic logout
+functionality by "forgetting" user credentials on the mobile device.
+