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