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