Bug fixed in result dialog.
[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     maxSpeed = 0;
44     distanceTraveled = 0;
45     lastAcceleration = 0;
46     lastDistance = 0;
47     lastSpeed = 0;
48     numOfIterations = 0;
49     totalTime = 0;
50     count = 0;
51
52     if(speedCheckPoints.count() == 0)
53     {
54         speedCheckPoints.append(10);
55         speedCheckPoints.append(20);
56         speedCheckPoints.append(30);
57         speedCheckPoints.append(40);
58         speedCheckPoints.append(50);
59         speedCheckPoints.append(60);
60         speedCheckPoints.append(70);
61         speedCheckPoints.append(80);
62         speedCheckPoints.append(90);
63         speedCheckPoints.append(100);
64     }
65
66     checkPointCounter = 0;
67     checkPoint = speedCheckPoints[checkPointCounter];
68
69 }
70
71
72 /**
73   * This is a main function for calculating various parameters. Accelerometer
74   * provides currentAcceleration and calling function measures time (seconds).
75   * This function should be called 20-30 times/second to minimize
76   * calculation error.
77
78   * To be added: ---
79   */
80 void Calculate::calculateParameters(double currentAcceleration, double seconds)
81 {
82     double force, power1, power2;
83
84     currentAcceleration *= G_ACCELERATION;
85     numOfIterations++;
86     totalTime = (totalTime + seconds);
87
88     // v=v0 + a*t
89     // v(n) = v(n-1)+(a(n) + a(n-1))*(seconds)/2
90
91     // First integration of acceleration provides speed
92     currentSpeed = (lastSpeed + (((currentAcceleration + lastAcceleration) * seconds) / 2));
93
94     // Update maximum speed
95     if (currentSpeed > maxSpeed)
96         maxSpeed = currentSpeed;
97
98     // Second integration: distance.
99     distanceTraveled = (lastDistance + (((currentSpeed + lastSpeed) * seconds) / 2));
100
101     // Average speed
102     averageSpeed = (distanceTraveled / totalTime);
103
104     // F=ma
105     force = (carWeight * currentAcceleration);
106
107     power1 = (force * currentSpeed);
108
109     power2 = ((AIR_DENSITY * (pow(currentSpeed, 3)
110              * (carFrontalArea * dragCoefficient))) / 2);
111
112     currentPower = ((power1 + power2) / WATTS_PER_HORSEPOWER);
113
114     // Save peak power
115     if ((currentPower > peakPower))
116     {
117         peakPower = currentPower;
118     }
119
120     if ((currentPower > 0))
121     {
122         averagePower = (averagePower + currentPower);
123     }
124     else
125     {
126         numOfIterations--;
127     }
128
129     if( (checkPoint > 0) && (currentSpeed*3.6 > checkPoint) )
130     {
131         //Update checkPoint
132         if( checkPointCounter <= speedCheckPoints.count() )
133         {
134             //Save time
135             valuesMap.insert( checkPoint, totalTime );
136             if( checkPointCounter < speedCheckPoints.count() )
137             {
138                 checkPoint = speedCheckPoints[checkPointCounter];
139             }
140             else
141             {
142                 checkPoint = 0;
143             }
144             checkPointCounter++;
145         }
146     }
147
148     // Check for movement
149     //accelStoppedCheck(currentAcceleration);
150
151     lastSpeed = currentSpeed;
152     lastAcceleration = currentAcceleration;
153     lastDistance = distanceTraveled;
154 }
155
156 /**
157   * This function checks if acceleration has stopped for
158   * a short period of time. Velocity is set to zero to avoid
159   * distance errors.
160   */
161 void Calculate::accelStoppedCheck(double currentAcceleration)
162 {
163     // counting number of acceleration samples that equals zero
164     if (currentAcceleration==0) {
165         count++;
166     } else {
167         count = 0;
168     }
169
170     // if count exceeds 25, we assume that velocity is zero
171     if (count >= 25)
172     {
173         currentSpeed=0;
174     }
175 }
176
177 // Getters and setters
178
179 double Calculate::getAverageSpeed()
180 {
181     return averageSpeed;
182 }
183
184 void Calculate::setAverageSpeed(double value)
185 {
186     averageSpeed = value;
187 }
188
189 double Calculate::getCurrentSpeed()
190 {
191     return currentSpeed;
192 }
193
194 void Calculate::setCurrentSpeed(double value)
195 {
196     currentSpeed = value;
197 }
198
199 double Calculate::getDistanceTraveled()
200 {
201     return distanceTraveled;
202 }
203
204 void Calculate::setDistanceTraveled(double value)
205 {
206     distanceTraveled = value;
207 }
208
209 double Calculate::getLastAcceleration()
210 {
211     return lastAcceleration;
212 }
213
214 void Calculate::setLastAcceleration(double value)
215 {
216     lastAcceleration = value;
217 }
218
219 double Calculate::getLastDistance()
220 {
221     return lastDistance;
222 }
223
224 void Calculate::setLastDistance(double value)
225 {
226     lastDistance = value;
227 }
228
229 double Calculate::getLastSpeed()
230 {
231     return lastSpeed;
232 }
233
234 void Calculate::setLastSpeed(double value)
235 {
236     lastSpeed = value;
237 }
238
239 long Calculate::getNumOfIterations()
240 {
241     return numOfIterations;
242 }
243
244 void Calculate::setNumOfIterations(long value)
245 {
246     numOfIterations = value;
247 }
248
249 double Calculate::getTotalTime()
250 {
251     return totalTime;
252 }
253
254 void Calculate::setTotalTime(double value)
255 {
256     totalTime = value;
257 }
258
259 double Calculate::getCurrentPower()
260 {
261     return currentPower;
262 }
263
264 void Calculate::setCurrentPower(double value)
265 {
266     currentPower = value;
267 }
268
269 double Calculate::getPeakPower()
270 {
271     return peakPower;
272 }
273
274 void Calculate::setPeakPower(double value)
275 {
276     peakPower = value;
277 }
278
279 double Calculate::getAveragePower()
280 {
281     if (numOfIterations > 0)
282     {
283         return (averagePower/numOfIterations);
284     }
285     else
286     {
287         return 0;
288     }
289 }
290
291 void Calculate::setAveragePower(double value)
292 {
293     averagePower = value;
294 }
295
296 double Calculate::getMaxSpeed()
297 {
298     return maxSpeed;
299 }
300
301 void Calculate::setMaxSpeed(double value)
302 {
303     maxSpeed = value;
304 }
305