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