2 * This file is part of jSpeed.
4 * jSpeed is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * jSpeed is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with jSpeed. If not, see <http://www.gnu.org/licenses/>.
19 #include <QtCore/QTime>
20 #include <QtCore/QDebug>
21 #include <QtCore/QTimer>
27 QString const TOTAL_FIELD = "odometer_total";
28 QString const TOTALTIME_FIELD = "odometer_totaltime";
29 QString const TRIP_FIELD = "odometer_trip";
30 QString const TRIPTIME_FIELD = "odometer_triptime";
31 QString const MAXSPEED_FIELD = "odometer_maxspeed";
32 QString const KM_UNIT = "km";
33 QString const MILE_UNIT = "mi";
34 QString const KM_SPEEDUNIT = "km/h";
35 QString const MILE_SPEEDUNIT = "mph";
36 QString const METER_UNIT = "m";
37 QString const FEET_UNIT = "feet";
38 double const FEET_MULTIPLIER = 3.2808399;
39 double const METER_MULTIPLIER = 1.0;
40 static const int FIX_TIMEOUT = 4000;
41 double const DEFAULT_SPEED_TRESHOLD = 8.0;
42 double const MIN_SPEED_TRESHOLD = 0.8;
43 double const SPEED_IGNORE_LEVEL = 0.01;
44 double const TRESHOLD_POINT1_EPS = 40.0;
45 double const TRESHOLD_POINT1_TRESHOLD = 10.0;
46 double const TRESHOLD_POINT2_EPS = 1.8;
47 double const TRESHOLD_POINT2_TRESHOLD = MIN_SPEED_TRESHOLD;
48 double const TRESHOLD_X = (TRESHOLD_POINT1_TRESHOLD - TRESHOLD_POINT2_TRESHOLD) / (TRESHOLD_POINT1_EPS - TRESHOLD_POINT2_EPS);
49 double const TRESHOLD_Y = TRESHOLD_POINT1_TRESHOLD - (TRESHOLD_POINT1_EPS * TRESHOLD_X);
52 Odometer::Odometer(): QObject(0), trip_(0), total_(0),
53 maxSpeed_(0), totalTime_(0), tripTime_(0), fixTimer_(0),
54 mainTimer_(0), emitUpdate_(true), location_(0), signalTimer_(0)
56 total_ = Settings::instance().value(TOTAL_FIELD, 0).toDouble();
57 totalTime_ = Settings::instance().value(TOTALTIME_FIELD, 0).toULongLong();
58 maxSpeed_ = Settings::instance().value(MAXSPEED_FIELD, 0).toDouble();
59 trip_ = Settings::instance().value(TRIP_FIELD, 0).toDouble();
60 tripTime_ = Settings::instance().value(TRIPTIME_FIELD, 0).toULongLong();
61 signalTimer_ = new QTimer(this);
62 signalTimer_->setSingleShot(false);
63 signalTimer_->setInterval(1000);
64 connect(signalTimer_, SIGNAL(timeout()), this, SIGNAL(timeUpdated()));
66 timeoutTimer_ = new QTimer(this);
67 timeoutTimer_->setSingleShot(true);
68 connect(timeoutTimer_, SIGNAL(timeout()), this, SLOT(fixTimeout()));
80 Odometer& Odometer::instance()
82 static Odometer instance;
86 void Odometer::start()
88 location_ = new Location;
89 connect(location_, SIGNAL(locationChanged(Location::Fix const&)),
90 this, SLOT(update(Location::Fix const&)));
100 void Odometer::update(Location::Fix const& fix)
104 fixTimer_ = new QTime();
108 int elapsed = fixTimer_->elapsed();
110 fixTimer_->restart();
111 timeoutTimer_->start(FIX_TIMEOUT);
113 if(fix.kmSpeed > SPEED_IGNORE_LEVEL)
115 double treshold = DEFAULT_SPEED_TRESHOLD;
119 treshold = fix.eps * TRESHOLD_X + TRESHOLD_Y;
121 if(treshold < MIN_SPEED_TRESHOLD)
123 treshold = MIN_SPEED_TRESHOLD;
127 if(fix.kmSpeed > treshold && fix.kmSpeed > maxSpeed_)
129 maxSpeed_ = fix.kmSpeed;
132 if(fix.kmSpeed > treshold && elapsed > 200 && elapsed < FIX_TIMEOUT)
134 double km = fix.kmSpeed * (static_cast<double>(elapsed) / (1000 * 3600));
157 void Odometer::fixTimeout()
159 if(latestFix_.kmSpeed > SPEED_IGNORE_LEVEL)
161 latestFix_ = Location::Fix();
168 double Odometer::getTrip() const
170 return trip_ * Location::getUnitMultiplier();
173 double Odometer::getAverageSpeed() const
175 int elapsed = getTripTime();
182 return (static_cast<double>(getTrip())) / (static_cast<double>(getTripTime()) / 3600.0);
185 double Odometer::getTotal() const
187 return total_ * Location::getUnitMultiplier();
190 double Odometer::getMaxSpeed() const
192 return maxSpeed_ * Location::getUnitMultiplier();
195 qulonglong Odometer::getTotalTime() const
197 return totalTime_ + timeAddition();
200 qulonglong Odometer::getTripTime() const
202 return tripTime_ + timeAddition();
205 void Odometer::resetTrip()
219 void Odometer::resetTotal()
232 void Odometer::resetAll()
242 void Odometer::store()
244 Settings::instance().setValue(TOTAL_FIELD, total_);
245 Settings::instance().setValue(TOTALTIME_FIELD, getTotalTime());
246 Settings::instance().setValue(TRIP_FIELD, trip_);
247 Settings::instance().setValue(TRIPTIME_FIELD, getTripTime());
248 Settings::instance().setValue(MAXSPEED_FIELD, maxSpeed_);
249 Settings::instance().sync();
252 Location::Fix const& Odometer::getLatestFix() const
257 double Odometer::getSignalStrength() const
264 return location_->getSignalStrength();
267 QString const& Odometer::getUnit()
269 if(Location::getUnit() == Location::KM)
279 QString const& Odometer::getSpeedUnit()
281 if(Location::getUnit() == Location::KM)
287 return MILE_SPEEDUNIT;
291 double Odometer::getUnitMultiplier()
293 return Location::getUnitMultiplier();
296 double Odometer::getMeterMultiplier()
298 if(Location::getUnit() == Location::KM)
300 return METER_MULTIPLIER;
304 return FEET_MULTIPLIER;
308 QString Odometer::getMeterUnit()
310 if(Location::getUnit() == Location::KM)
320 void Odometer::updateUnit()
322 QString unit = Settings::instance().value("unit", "km").toString();
326 Location::setUnit(Location::KM);
328 else if(unit == "mile")
330 Location::setUnit(Location::MILE);
340 void Odometer::startTiming()
342 signalTimer_->start();
346 mainTimer_->restart();
350 mainTimer_ = new QTime();
352 signalTimer_->start();
355 void Odometer::endTiming()
357 signalTimer_->stop();
364 int elapsed = mainTimer_->elapsed() / 1000;
365 totalTime_ += elapsed;
366 tripTime_ += elapsed;
371 void Odometer::resetTiming()
382 int Odometer::timeAddition() const
386 return mainTimer_->elapsed() / 1000;