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