1 /*
2  * Calculate class to process accelerometer data
3  *
4  * @author      Kai Rasilainen
5  * @copyright   (c) 2010 Speed Freak team
7  */
9 #include "calculate.h"
10 #include <math.h>
12 #include <QFile>
13 #include <QString>
14 #include <QTimer>
15 #include <QRegExp>
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;
22 const double carFrontalArea = 1.5;
23 const double dragCoefficient = 0.31;
24 const int carWeight = 850;
26 Calculate::Calculate()
27 {
28     this->reset();
29 }
31 Calculate::~Calculate()
32 {
34 }
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;
48     speedCheckPoints.append(10);
49     speedCheckPoints.append(20);
50     speedCheckPoints.append(30);
51     speedCheckPoints.append(40);
53 }
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.
62   * To be added: ---
63   */
64 void Calculate::calculateParameters(double currentAcceleration, double seconds)
65 {
66     double force, power1, power2;
68     currentAcceleration *= G_ACCELERATION;
69     numOfIterations++;
70     totalTime = (totalTime + seconds);
72     // v=v0 + a*t
73     // v(n) = v(n-1)+(a(n) + a(n-1))*(seconds)/2
75     // First integration of acceleration provides speed
76     currentSpeed = (lastSpeed + (((currentAcceleration + lastAcceleration) * seconds) / 2));
78     // Second integration: distance.
79     distanceTraveled = (lastDistance + (((currentSpeed + lastSpeed) * seconds) / 2));
81     // Average speed
82     averageSpeed = (distanceTraveled / totalTime);
84     // F=ma
85     force = (carWeight * currentAcceleration);
87     power1 = (force * currentSpeed);
89     power2 = ((AIR_DENSITY * (pow(currentSpeed, 3)
90              * (carFrontalArea * dragCoefficient))) / 2);
92     currentPower = ((power1 + power2) / WATTS_PER_HORSEPOWER);
94     // Save peak power
95     if ((currentPower > peakPower))
96     {
97         peakPower = currentPower;
98     }
100     if ((currentPower > 0))
101     {
102         averagePower = (averagePower + currentPower);
103     }
104     else
105     {
106         numOfIterations--;
107     }
109     // Checkpoints
110     if ((lastSpeed == 0))
111     {
112         lastCheckpoint = 0;
113     }
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     }
128     // Check for movement
129     accelStoppedCheck(currentAcceleration);
131     lastSpeed = currentSpeed;
132     lastAcceleration = currentAcceleration;
133     lastDistance = distanceTraveled;
134 }
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 {
144     // counting number of acceleration samples that equals zero
145     if (currentAcceleration==0) {
146         count++;
147     } else {
148         count = 0;
149     }
151     // if count exceeds 15, we assume that velocity is zero
152     if (count >= 15)
153     {
154         currentSpeed=0;
155     }
156 }
158 // Getters and setters
160 double Calculate::getAverageSpeed()
161 {
162     return averageSpeed;
163 }
165 void Calculate::setAverageSpeed(double value)
166 {
167     averageSpeed = value;
168 }
170 double Calculate::getCurrentSpeed()
171 {
172     return currentSpeed;
173 }
175 void Calculate::setCurrentSpeed(double value)
176 {
177     currentSpeed = value;
178 }
180 double Calculate::getDistanceTraveled()
181 {
182     return distanceTraveled;
183 }
185 void Calculate::setDistanceTraveled(double value)
186 {
187     distanceTraveled = value;
188 }
190 double Calculate::getLastAcceleration()
191 {
192     return lastAcceleration;
193 }
195 void Calculate::setLastAcceleration(double value)
196 {
197     lastAcceleration = value;
198 }
200 double Calculate::getLastDistance()
201 {
202     return lastDistance;
203 }
205 void Calculate::setLastDistance(double value)
206 {
207     lastDistance = value;
208 }
210 double Calculate::getLastSpeed()
211 {
212     return lastSpeed;
213 }
215 void Calculate::setLastSpeed(double value)
216 {
217     lastSpeed = value;
218 }
220 long Calculate::getNumOfIterations()
221 {
222     return numOfIterations;
223 }
225 void Calculate::setNumOfIterations(long value)
226 {
227     numOfIterations = value;
228 }
230 double Calculate::getTotalTime()
231 {
232     return totalTime;
233 }
235 void Calculate::setTotalTime(double value)
236 {
237     totalTime = value;
238 }
240 double Calculate::getCurrentPower()
241 {
242     return currentPower;
243 }
245 void Calculate::setCurrentPower(double value)
246 {
247     currentPower = value;
248 }
250 double Calculate::getPeakPower()
251 {
252     return peakPower;
253 }
255 void Calculate::setPeakPower(double value)
256 {
257     peakPower = value;
258 }
260 double Calculate::getAveragePower()
261 {
262     if (numOfIterations > 0)
263     {
264         return (averagePower/numOfIterations);
265     }
266     else
267     {
268         return 0;
269     }
270 }
272 void Calculate::setAveragePower(double value)
273 {
274     averagePower = value;
275 }