Modifications to project structure, bug fixes etc.
[speedfreak] / Client / calculate.cpp
1 /*
2  * Calculate class to process accelerometer data
3  *
4  * @author      Kai Rasilainen
5  * @copyright   (c) 2010 Speed Freak team
6  * @license     http://opensource.org/licenses/gpl-license.php GNU Public License
7  */
8
9 #include "calculate.h"
10 #include <math.h>
11
12 #include <QFile>
13 #include <QString>
14 #include <QTimer>
15 #include <QRegExp>
16
17 const double G_ACCELERATION = 9.80665;
18 const double SECONDS_IN_HOUR = 3600;
19 const double AIR_DENSITY = 1.225;
20 const double WATTS_PER_HORSEPOWER = 745.69987158227025;
21
22 const double carFrontalArea = 1.5;
23 const double dragCoefficient = 0.31;
24 const int carWeight = 850;
25
26 Calculate::Calculate()
27 {
28     this->reset();
29 }
30
31 Calculate::~Calculate()
32 {
33
34 }
35
36 void Calculate::reset()
37 {
38     averageSpeed = 0;
39     averagePower = 0;
40     peakPower = 0;
41     currentPower = 0;
42     currentSpeed = 0;
43     distanceTraveled = 0;
44     lastAcceleration = 0;
45     lastDistance = 0;
46     lastSpeed = 0;
47     numOfIterations = 0;
48     totalTime = 0;
49     //count = 0;
50
51     speedCheckPoints.append(10);
52     speedCheckPoints.append(20);
53     speedCheckPoints.append(30);
54     speedCheckPoints.append(40);
55
56 }
57
58
59 /**
60   * This is a main function for calculating various parameters. Accelerometer
61   * provides currentAcceleration and calling function measures time (seconds).
62   * This function should be called 20-30 times/second to minimize
63   * calculation error.
64
65   * To be added: ---
66   */
67 void Calculate::calculateParameters(double currentAcceleration, double seconds)
68 {
69     double force, power1, power2;
70
71     currentAcceleration *= G_ACCELERATION;
72     numOfIterations++;
73     totalTime = (totalTime + seconds);
74
75     // v=v0 + a*t
76     // v(n) = v(n-1)+(a(n) + a(n-1))*(seconds)/2
77
78     // First integration of acceleration provides speed
79     currentSpeed = (lastSpeed + (((currentAcceleration + lastAcceleration) * seconds) / 2));
80
81     // Second integration: distance.
82     distanceTraveled = (lastDistance + (((currentSpeed + lastSpeed) * seconds) / 2));
83
84     // Average speed
85     averageSpeed = (distanceTraveled / totalTime);
86
87     // F=ma
88     force = (carWeight * currentAcceleration);
89
90     power1 = (force * currentSpeed);
91
92     power2 = ((AIR_DENSITY * (pow(currentSpeed, 3)
93              * (carFrontalArea * dragCoefficient))) / 2);
94
95     currentPower = ((power1 + power2) / WATTS_PER_HORSEPOWER);
96
97     // Save peak power
98     if ((currentPower > peakPower))
99     {
100         peakPower = currentPower;
101     }
102
103     if ((currentPower > 0))
104     {
105         averagePower = (averagePower + currentPower);
106     }
107     else
108     {
109         numOfIterations--;
110     }
111
112     // Checkpoints
113     if ((lastSpeed == 0))
114     {
115         lastCheckpoint = 0;
116     }
117
118     // List of checkpoints
119     if (!(speedCheckPoints.isEmpty()))
120     {
121         foreach (double speed, speedCheckPoints)
122         {
123             if ((lastCheckpoint != floor(speed)) && (floor(getCurrentSpeed()) == floor(speed)))
124             {
125                 emit checkPointReached(totalTime, getCurrentSpeed());
126                 lastCheckpoint = floor(getCurrentSpeed());
127             }
128         }
129     }
130
131     // Check for movement
132     //accelStoppedCheck(currentAcceleration);
133
134     lastSpeed = currentSpeed;
135     lastAcceleration = currentAcceleration;
136     lastDistance = distanceTraveled;
137 }
138
139 /**
140   * This function checks if acceleration has stopped for
141   * a short period of time. Velocity is set to zero to avoid
142   * distance errors.
143   */
144 /*
145 void Calculate::accelStoppedCheck(double currentAcceleration)
146 {
147
148     // counting number of acceleration samples that equals zero
149     if (currentAcceleration==0) {
150         count++;
151     } else {
152         count = 0;
153     }
154
155     // if count exceeds 15, we assume that velocity is zero
156     if (count >= 15)
157     {
158         currentSpeed=0;
159     }
160 }
161 */
162 // Getters and setters
163
164 double Calculate::getAverageSpeed()
165 {
166     return averageSpeed;
167 }
168
169 void Calculate::setAverageSpeed(double value)
170 {
171     averageSpeed = value;
172 }
173
174 double Calculate::getCurrentSpeed()
175 {
176     return currentSpeed;
177 }
178
179 void Calculate::setCurrentSpeed(double value)
180 {
181     currentSpeed = value;
182 }
183
184 double Calculate::getDistanceTraveled()
185 {
186     return distanceTraveled;
187 }
188
189 void Calculate::setDistanceTraveled(double value)
190 {
191     distanceTraveled = value;
192 }
193
194 double Calculate::getLastAcceleration()
195 {
196     return lastAcceleration;
197 }
198
199 void Calculate::setLastAcceleration(double value)
200 {
201     lastAcceleration = value;
202 }
203
204 double Calculate::getLastDistance()
205 {
206     return lastDistance;
207 }
208
209 void Calculate::setLastDistance(double value)
210 {
211     lastDistance = value;
212 }
213
214 double Calculate::getLastSpeed()
215 {
216     return lastSpeed;
217 }
218
219 void Calculate::setLastSpeed(double value)
220 {
221     lastSpeed = value;
222 }
223
224 long Calculate::getNumOfIterations()
225 {
226     return numOfIterations;
227 }
228
229 void Calculate::setNumOfIterations(long value)
230 {
231     numOfIterations = value;
232 }
233
234 double Calculate::getTotalTime()
235 {
236     return totalTime;
237 }
238
239 void Calculate::setTotalTime(double value)
240 {
241     totalTime = value;
242 }
243
244 double Calculate::getCurrentPower()
245 {
246     return currentPower;
247 }
248
249 void Calculate::setCurrentPower(double value)
250 {
251     currentPower = value;
252 }
253
254 double Calculate::getPeakPower()
255 {
256     return peakPower;
257 }
258
259 void Calculate::setPeakPower(double value)
260 {
261     peakPower = value;
262 }
263
264 double Calculate::getAveragePower()
265 {
266     if (numOfIterations > 0)
267     {
268         return (averagePower/numOfIterations);
269     }
270     else
271     {
272         return 0;
273     }
274 }
275
276 void Calculate::setAveragePower(double value)
277 {
278     averagePower = value;
279 }
280
281