Acceleration calculation fixed.
[speedfreak] / Client / carmainwindow.cpp
1 /*
2  * CarMainWindow main class
3  *
4  * @author     Toni Jussila <toni.jussila@fudeco.com>
5  * @author     Janne Änäkkälä <janne.anakkala@fudeco.com>
6  * @author     Tiina Kivilinna-Korhola <tiina.kivilinna-korhola@fudeco.com>
7  * @author     Olavi Pulkkinen <olavi.pulkkinen@fudeco.com>
8  * @author     Rikhard Kuutti <rikhard.kuutti@fudeco.com>
9  * @author     Kai Rasilainen <kai.rasilainen@fudeco.com>
10  * @copyright  (c) 2010 Speed Freak team
11  * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
12  */
13
14 #include "carmainwindow.h"
15 #include "math.h"
16
17 #define kAccelerometerSampleRate    40
18 #define kFilteringFactor            0.1
19 #define kSecondsInHour              3600
20
21 /**
22   *Constructor of this class.
23   *@param QWidget pointer to parent object. By default the value is NULL.
24   */
25 CarMainWindow::CarMainWindow(QWidget *parent):QMainWindow(parent), ui(new Ui::CarMainWindow)
26 {
27     ui->setupUi(this);
28     ui->tabWidget->setCurrentWidget(this->ui->StartTab);
29
30     //Disable start buttons before calibration
31     ui->autoStartButton->setEnabled(false);
32     ui->manualStartButton->setEnabled(false);
33
34     result = new ResultDialog();
35     //measure = new MeasureDialog();
36     welcomeDialog = new WelcomeDialog();
37     welcomeDialog->show();
38
39     initComboBoxStartTabUnits();
40     initListViewStartTabAccelerationCategories();
41
42     myLogin = new LoginWindow(this);
43     myCategorylist = new CategoryList();
44     myHttpClient = new HttpClient(this);
45     myRegistration = new Registration(this);
46     connect(myRegistration,SIGNAL(sendregistration()),this,SLOT(regUserToServer()));
47     connect(myLogin,SIGNAL(userNameChanged()),this,SLOT(userLogin()));
48     connect(myHttpClient->myXmlreader, SIGNAL(receivedCategoryList()), this, SLOT(setCategoryCompoBox()));
49     connect(myHttpClient->myXmlreader, SIGNAL(receivedTop10List()), this, SLOT(showTop10()));
50     myRoute = new RouteDialog( this);
51
52     //GPS
53     location = new Maemo5Location(this);
54     gpsData = new GPSData(location);
55     connect(location,SIGNAL(agnss()),this,SLOT(gpsStatus()));
56     gpsTime = new QDateTime();
57     gpsTimer = new QTimer();
58     connect(gpsTimer, SIGNAL(timeout()),this, SLOT(gpsTimerTimeout()));
59     gpsSpeedNow = 0.0;
60     gpsSpeedPrevious = 0.0;
61     gpsAcceleration = 0.0;
62     timeFromGps = 0.0; //Measure-tab view.
63     gpsSpeed = 0.0;
64
65     this->time = 0;
66     this->speed = 0;
67     counterForSaveResults = 0;
68     timer = new QTimer();
69
70     // Accelerometer
71     accelerometer = new Accelerometer();
72
73     reverseAccelerationFlag = false;
74     vehicleStartedMoving = false;
75     isNewRun = true;
76     isSetup = false;
77     stopTime = 0;
78     accelerationStartThreshold = 0.1;
79
80     accelerometerTimer = new QTimer(this);
81     connect(accelerometerTimer, SIGNAL(timeout()), this, SLOT(readAccelerometerData()));
82     //accelerometerTimer->start(kAccelerometerSampleRate);
83
84     // Calculate
85     calculate = new Calculate();
86     connect(calculate, SIGNAL(checkPointReached()), this, SLOT(handleCheckPoint()));
87
88     resetAccelerometerMeasurements();
89
90     measures = new Measures();
91     this->initializeMeasures();
92
93     this->timer->setInterval(100);
94
95     connect(this->timer, SIGNAL(timeout()), this, SLOT(after_timeout()));
96     connect(myLogin, SIGNAL( userNameChanged()), this, SLOT(updateUserName()));
97
98     ui->labelMeasureTabResult->hide();
99     ui->pushButtonShowResultDialog->setEnabled(false);
100     ui->pushButtonShowResultDialog->setEnabled(false);
101
102     this->setWindowTitle("Speed Freak");
103 }
104
105 /**
106   *Destructor of this class. Deletes all dynamic objects and sets them to NULL.
107   */
108 CarMainWindow::~CarMainWindow()
109 {
110     delete ui;
111     ui = NULL;
112     //delete result;
113     //delete measure;
114     delete myCategorylist;
115     myCategorylist = NULL;
116     delete welcomeDialog;
117     welcomeDialog = NULL;
118     delete myRoute;
119     myRoute = NULL;
120     delete gpsData;
121     gpsData = NULL;
122     delete gpsTime;
123     gpsTime = NULL;
124
125     //Route-tab view
126     gpsSpeedNow = 0.0;
127     gpsSpeedPrevious = 0.0;
128     gpsAcceleration = 0.0;
129     timeFromGps = 0.0;
130     gpsSpeed = 0.0;
131     gpsUpdateTime = 0;
132 }
133
134 /**
135   *This function is used to .
136   *@param
137   */
138 void CarMainWindow::changeEvent(QEvent *e)
139 {
140     QMainWindow::changeEvent(e);
141     switch (e->type()) {
142     case QEvent::LanguageChange:
143         ui->retranslateUi(this);
144         break;
145     default:
146         break;
147     }
148 }
149
150 /**
151   *This slot function is called when ever list view is update. Start-tab view.
152   */
153 void CarMainWindow::on_listViewStartTabAccelerationCategories_clicked(QModelIndex index)
154 {
155     QString str = index.data().toString();
156     QStringList list = str.split("-");
157     QStringList list2 = list[1].split(" ");
158
159     ui->lineEditStartTabMin->setText(list[0]);
160     ui->lineEditStartTabMax->setText(list2[0]);
161     updateComboBoxStartTabUnits(list2[1]);
162 }
163
164 /**
165   *This slot function is called when ever auto start button clicked. Start-tab view.
166   *@todo Check setDiagramGapStem(100) <- (choiceInt == 2)
167   */
168 void CarMainWindow::on_autoStartButton_clicked()
169 {
170     initializeMeasures();
171     resetAccelerometerMeasurements();
172     ui->pushButtonSendResult->setEnabled(false);
173     ui->pushButtonShowResultDialog->setEnabled(false);
174     choice = ui->listViewStartTabAccelerationCategories->currentIndex();
175     choiceInt = choice.row();
176     //qDebug() << "choiceInt" << choiceInt << " " << catList.at(choiceInt);
177     if (choiceInt == 0)
178     {
179         ui->labelMeasureTabHeader->setText("Accelerate to 40 km/h");
180         result->setDiagramGapStem(75);
181     }
182     else if (choiceInt == 1)
183     {
184         ui->labelMeasureTabHeader->setText("Accelerate to 100 km/h");
185         result->setDiagramGapStem(30);
186     }   
187     else if (choiceInt == 2)
188     {
189         ui->labelMeasureTabHeader->setText("Accelerate to 10 km/h");
190         result->setDiagramGapStem(100);
191     }
192     else
193     {
194         ui->labelMeasureTabHeader->setText("Accelerate to 80 km/h");
195         result->setDiagramGapStem(37.5);
196     }
197     ui->labelMeasureTabResult->setText("");
198
199     this->accelerometerTimer->start(kAccelerometerSampleRate);
200     this->timer->start();
201     this->time = 0;
202     this->speed = 0;
203     ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
204 }
205
206 /**
207   *This slot function is called when ever list view is update. Start-tab view.
208   *@param QString unit.
209   */
210 void CarMainWindow::updateComboBoxStartTabUnits(QString unit)
211 {
212     ui->comboBoxStartTabUnits->setCurrentIndex(ui->comboBoxStartTabUnits->findText(unit, Qt::MatchExactly));
213 }
214
215 /**
216   *This function is used to init unit combobox. Start-tab view.
217   */
218 void CarMainWindow::initComboBoxStartTabUnits()
219 {
220     units << "km/h" << "km" << "h" << "m" << "min" << "Mile" << "Mph" << "in" << "ft" << "yrd";
221     ui->comboBoxStartTabUnits->addItems(units);
222 }
223
224 /**
225   *This function is used to set items to unit combobox. Start-tab view.
226   *@param QStringlist units
227   */
228 void CarMainWindow::setComboBoxStartTabUnits(QStringList units)
229 {
230     ui->comboBoxStartTabUnits->addItems(units);
231 }
232
233 /**
234   *This function is used to init listViewStartTabAccelerationCategories. Start-tab view.
235   *@todo During development categories index values that are used for measuring are hardcoded
236   *@todo and accelerationCategoriesStartTab and catList are used instead of using
237   *@todo CategoryList::categoryList and CategoryList::cats.
238   */
239 void CarMainWindow::initListViewStartTabAccelerationCategories()
240 {
241     //Connect the user`s choice fron GUI to a correct variable name
242     catList.insert(0,"acceleration-0-40");
243     catList.insert(1,"acceleration-0-100");
244     catList.insert(2,"acceleration-0-10");
245
246     accelerationCategoriesStartTab << "0-40 km/h" << "0-100 km/h" << "0-10 km/h";
247     //<< "0-1/4 Mile" << "0-1/8 Mile" << "50-100 Mile" << "0-60 Mph" << "0-100 m" << "0-50 ft" << "0-50 yrd" << "0-500 in";
248     QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
249     ui->listViewStartTabAccelerationCategories->setModel(model);
250 }
251
252 /**
253   *This function is used to set items to listViewStartTabAccelerationCategories. Start-tab view.
254   *@param QStringlist accelerationCategoriesStartTab
255   */
256 void CarMainWindow::setListViewStartTabAccelerationCategories(QStringList accelerationCategoriesStartTab)
257 {
258     QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
259     ui->listViewStartTabAccelerationCategories->setModel(model);
260 }
261
262 void CarMainWindow::setLabelInfoToUser(QString infoText)
263 {
264     ui->labelInfoToUser->setText(infoText);
265 }
266
267 /**
268   *This function is used to set items to category combobox. Top-tab view.
269   *@param
270   */
271 void CarMainWindow::setCategoryCompoBox()
272 {
273     qDebug() << "_setCategoryCompoBox";
274     ui->comboBoxTopCategory->addItems(myHttpClient->myXmlreader->myCategoryList->getCategoryList());
275 }
276
277 /**
278   *This function prcesses UI updating after a new top10List has been received.
279   *@todo Check where limitNr is taken, fixed or user input, see on_comboBoxTopCategory_currentIndexChanged.
280   */
281 void CarMainWindow::showTop10()
282 {
283     int limitNr = 5;
284     setListViewTopList(recentCategory, limitNr);
285 }
286
287 /**
288   *This function is used to set items to labelTopList. Top-tab view.
289   *@param Category
290   *@param Size, number of results.
291   */
292 void CarMainWindow::setListViewTopList(QString category, int size)
293 {
294     qDebug() << "_setListViewTopList";
295     QString topList;
296     topList.append(myHttpClient->myXmlreader->myCategoryList->getTopList(category, size));
297     ui->labelTopList->setText(topList);
298 }
299
300 /**
301   *This slot function is called when speed is achieved in measure dialog. Opens result dialog.
302   */
303 void CarMainWindow::openResultView()
304 {
305
306 }
307
308 /**
309   *This slot function is called when registrate button is clicked.
310   */
311 void CarMainWindow::on_registratePushButton_clicked()
312 {
313     myRegistration->show();
314 }
315
316 /**
317   *This slot function is called when ever refresh button clicked. Top-tab view.
318   */
319 void CarMainWindow::on_buttonTopRefresh_clicked()
320 {
321     myHttpClient->requestCategories();
322 }
323
324 /**
325   *This slot function is called when ever category combobox current index changed. Top-tab view.
326   *@param QString category.
327   *@todo Check where limitNr is taken, fixed or user input, see showTop10.
328   */
329 void CarMainWindow::on_comboBoxTopCategory_currentIndexChanged(QString category)
330 {
331     qDebug() << "_on_comboBoxTopCategory_currentIndexChanged: " << category;
332     recentCategory = category;      //for showTop10()
333     int limitNr = 5;
334     QString limit = QString::number(limitNr);
335     myHttpClient->requestTopList(category, limit);
336 }
337
338 /**
339   *This slot function is called when set/change user button is clicked.
340   */
341 void CarMainWindow::on_setUserPushButton_clicked()
342 {
343     myLogin->show();
344 }
345
346 /**
347   *@brief Just for development, for the real button is not shown until
348   *measurin started and there are results.
349   *@todo Implement with real code and yet leave sendXml in the bottom in use.
350   */
351 void CarMainWindow::on_manualStartButton_clicked()
352 {
353
354 }
355
356 /**
357   * This slot function is called when timer gives timeout signal. Checks current speed
358   * and stores times in measure class.
359   */
360 void CarMainWindow::after_timeout()
361 {
362     if ( gpsSpeed > 1.0 )
363     {
364         timeFromGps += 0.1;
365     }
366 }
367
368 /**
369   * Initializes measures class's member variables.
370   */
371 void CarMainWindow::initializeMeasures()
372 {
373     measures->setTime10kmh(0);
374     measures->setTime20kmh(0);
375     measures->setTime30kmh(0);
376     measures->setTime40kmh(0);
377     measures->setTime50kmh(0);
378     measures->setTime60kmh(0);
379     measures->setTime70kmh(0);
380     measures->setTime80kmh(0);
381     measures->setTime90kmh(0);
382     measures->setTime100kmh(0);
383 }
384
385 /**
386   * This slot function is called when Abort button is clicked.
387   */
388 void CarMainWindow::on_pushButtonMeasureTabAbort_clicked()
389 {
390     ui->pushButtonSendResult->setEnabled(false);
391     ui->pushButtonShowResultDialog->setEnabled(false);
392     ui->labelMeasureTabResult->hide();
393     ui->labelMeasureTabTime->setText("");
394     ui->labelMeasureTabSpeed->setText("");
395     measures->setTime10kmh(0);
396     measures->setTime20kmh(0);
397     measures->setTime30kmh(0);
398     measures->setTime40kmh(0);
399     measures->setTime50kmh(0);
400     measures->setTime60kmh(0);
401     measures->setTime70kmh(0);
402     measures->setTime80kmh(0);
403     measures->setTime90kmh(0);
404     measures->setTime100kmh(0);
405     this->accelerometerTimer->stop();
406     this->timer->stop();
407     this->time = 0;
408     this->speed = 0;
409     ui->tabWidget->setCurrentWidget(this->ui->StartTab);
410     //this->close();
411
412     //GPS
413     gpsSpeed = 0.0;
414     timeFromGps = 0.0;
415 }
416
417 /**
418   *This slot function is called when pushButtonSendResult is clicked.
419   *@todo Use real category value.
420   */
421 void CarMainWindow::on_pushButtonSendResult_clicked()
422 {
423     //Pick up relevant category name and pass it to the server
424     myHttpClient->sendResultXml(catList.at(choiceInt));
425     ui->pushButtonSendResult->setEnabled(false);
426 }
427
428 void CarMainWindow::updateUserName()
429 {
430     QString newUserName;
431
432     newUserName = myLogin->getUserName();
433     ui->userNameLabel->setText( "User: " + newUserName);
434
435     if (newUserName.length())
436     {
437        ui->setUserPushButton->setText( "Change User");
438        this->setWindowTitle("Speed Freak - " + newUserName);
439     }
440     else
441     {
442         ui->setUserPushButton->setText( "Set User");
443         this->setWindowTitle("Speed Freak");
444     }
445 }
446
447 void CarMainWindow::regUserToServer()
448 {
449     myHttpClient->requestRegistration();
450 }
451
452
453 void CarMainWindow::on_drawRoutePushButton_clicked()
454 {
455     QString routeFile = QString("route.txt");
456     if (myRoute->readRouteFromFile( routeFile) == true)
457     {
458         myRoute->show();
459     }
460 }
461
462 /**
463   * Opens result dialog when show result button is clicked.
464   * Sends measures as parameter to the resultdialogs saveMeasuresToArray-function.
465   */
466 void CarMainWindow::on_pushButtonShowResultDialog_clicked()
467 {
468     result->saveMeasuresToArray(measures);
469     this->result->show();
470 }
471
472 void CarMainWindow::userLogin()
473 {
474     myHttpClient->checkLogin();
475 }
476
477 /**
478   * Resets Accelerometer measurement variables
479   */
480 void CarMainWindow::resetAccelerometerMeasurements()
481 {
482     currentAcceleration = 0;
483     currentAccelerationString = "";
484     currentSpeed = "";
485     currentTime = 0;
486     distanceTraveled = "";
487     //firstAcceleration = 0;
488     //horsepower = null;
489     isNewRun = true;
490     //lastScreenUpdateInSeconds = 0;
491     previousTime = 0;
492     reverseAccelerationFlag = false;
493     stopWatch.start();
494     //accelerometer->stop();
495     totalTime = "";
496     vehicleStartedMoving = false;
497     calculate->reset();
498 }
499
500 /**
501   * This function is called to handle checkpoints
502   *@param totalTime total time elapsed since starting measurements
503   *@param currentSpeed current speed of the device
504   */
505 void CarMainWindow::handleCheckPoint(double totalTime, double currentSpeed)
506 {
507     switch (counterForSaveResults)
508     {
509     case 0:
510         measures->setTime10kmh(totalTime);
511         break;
512
513     case 1:
514         measures->setTime20kmh(totalTime);
515         break;
516
517     case 2:
518         measures->setTime30kmh(totalTime);
519         break;
520
521     case 3:
522         measures->setTime40kmh(totalTime);
523         break;
524
525     case 4:
526         measures->setTime50kmh(totalTime);
527         break;
528
529     case 5:
530         measures->setTime60kmh(totalTime);
531         break;
532
533     case 6:
534         measures->setTime70kmh(totalTime);
535         break;
536
537     case 7:
538         measures->setTime80kmh(totalTime);
539         break;
540
541     case 8:
542         measures->setTime90kmh(totalTime);
543         break;
544
545     case 9:
546         measures->setTime100kmh(totalTime);
547         break;
548
549     default:
550         break;
551     }
552     counterForSaveResults++;
553
554     if (choiceInt == 0 && measures->getTime40kmh() != 0)
555     {
556         setTimeAxisGapAndShowResult(measures->getTime40kmh());
557         this->timer->stop();
558         this->accelerometerTimer->stop();
559         this->time = 0;
560         this->speed = 0;
561         counterForSaveResults = 0;
562     }
563     else if (choiceInt == 1 && measures->getTime100kmh() != 0)
564     {
565         setTimeAxisGapAndShowResult(measures->getTime100kmh());
566         this->timer->stop();
567         this->accelerometerTimer->stop();
568         this->time = 0;
569         this->speed = 0;
570         counterForSaveResults = 0;
571     }
572     else if (choiceInt == 2 && measures->getTime10kmh() != 0)
573     {
574         setTimeAxisGapAndShowResult(measures->getTime10kmh());
575         this->timer->stop();
576         this->accelerometerTimer->stop();
577         this->time = 0;
578         this->speed = 0;
579         counterForSaveResults = 0;
580     }
581     else if (choiceInt != 1 && choiceInt != 0 && measures->getTime80kmh() != 0)
582     {
583         setTimeAxisGapAndShowResult(measures->getTime80kmh());
584         this->timer->stop();
585         this->accelerometerTimer->stop();
586         this->time = 0;
587         this->speed = 0;
588         counterForSaveResults = 0;
589     }
590     else
591     {
592         qDebug() << "something wrong in handleCheckPoint()";
593     }
594 }
595
596 /**
597   *This function is called to read (and process) data from the accelerometer
598   */
599 void CarMainWindow::readAccelerometerData()
600 {
601     QString s;
602     double changeInAcceleration = 0;
603     qreal x, y, z;
604
605     accelerometer->getAcceleration(x, y, z);
606
607     //  keep the following line as close to the SetKinematicsProperties method as possible
608     currentTime = stopWatch.elapsed();
609
610     //accelerometer->smoothData(x, y, z);
611
612     // Apply calibration
613     x -= accelerometer->getCalibrationX();
614     y -= accelerometer->getCalibrationY();
615     z -= accelerometer->getCalibrationZ();
616
617     QString str = QString("acc x: " + QString::number(x) + "\n" +
618                           "acc y: " + QString::number(y) + "\n" +
619                           "acc z: " + QString::number(z) + "\n");
620
621     currentAcceleration = z;//sqrt(x*x + y*y + z*z);
622     changeInAcceleration = currentAcceleration;
623
624     if (((fabs(changeInAcceleration) <= accelerationStartThreshold)
625                 && !vehicleStartedMoving))
626     {
627         return;
628     }
629     else if(!vehicleStartedMoving)
630     {
631         vehicleStartedMoving = true;
632         stopWatch.start();
633         previousTime = 0;
634         currentTime = 0;
635     }
636
637     calculate->calculateParameters(changeInAcceleration, (currentTime - previousTime)/1000);
638     previousTime = currentTime;
639
640     s.sprintf("%.2f", changeInAcceleration);
641     currentAccelerationString = s;
642
643     speed = 0.0;
644     speed = calculate->getCurrentSpeed();
645     speed = speed*3.6;//((speed*1000)/kSecondsInHour);
646     s.sprintf("%.1f", speed);
647     currentSpeed = s;
648
649     s.sprintf("%.2f", calculate->getDistanceTraveled());
650     distanceTraveled = s;
651
652     // TODO
653     //distanceTraveled;
654     //horsepower;
655
656     time = calculate->getTotalTime();
657
658     s.sprintf("%.2f", time);
659     totalTime = s;
660
661     str.append("ca: " + currentAccelerationString + " G\n" );
662     str.append("cspeed: " + currentSpeed + " km/h \n" );
663     str.append("dist: " + distanceTraveled + " m \n" );
664     str.append("time: " + totalTime + " s \n" );
665
666     if ((stopTime > 0) && (previousTime >= stopTime))
667     {
668         // we want to end at a stopping point that the user chose
669         // output results
670         resetAccelerometerMeasurements();
671     }
672 }
673
674 /**
675   *This function is used to calibrate accelerometer
676   */
677 void CarMainWindow::calibrateAccelerometer()
678 {
679     resetAccelerometerMeasurements();
680     accelerometer->calibrate();
681 }
682
683 /**
684   *This slot function is called when GPS on checkbox state changed. Route-tab view.
685   *@param int GPSState
686   */
687 void CarMainWindow::on_gpsOnCheckBox_stateChanged(int GPSState)
688 {
689     //Stop polling GPS. Route-tab view.
690     if (GPSState == 0)
691     {
692         ui->labelRouteTabGPSStatus->setText("GPS status: GPS off");
693         location->stopPollingGPS();
694         gpsUpdateTime = 0;
695         gpsTimer->stop();
696     }
697     //Start polling GPS. Route-tab view.
698     else
699     {
700         ui->labelRouteTabGPSStatus->setText("GPS status: GPS on");
701         location->startPollingGPS();
702     }
703 }
704
705 /**
706   *This slot function is called when GPS status changed. Route- and measure-tab view.
707   */
708 void CarMainWindow::gpsStatus()
709 {
710     //IF GPS checkbox is ON
711     if (ui->gpsOnCheckBox->isChecked())
712     {
713         //If GPS find 4 satellite.
714         if (location->getSatellitesInUse() >= 4)
715         {
716             //Set gps status. Route-tab view.
717             ui->labelRouteTabGPSStatus->setText("GPS ready");
718
719             //Set time. Route-tab view.
720             gpsTime->setTime_t(location->getTime());
721             QString gpsDateNow = gpsTime->toString("dd.MM.yyyy hh:mm:ss");
722             ui->labelRouteTabGPSTime->setText("GPS time: " + gpsDateNow);
723
724             //Set latitude & longitude. Route-tab view.
725             ui->labelRouteTabLatitude->setText("Latitude: " + QString::number(location->getLatitude()));
726             ui->labelRouteTabLongitude->setText("Longitude: " + QString::number(location->getLongitude()));
727
728             //Set rec status. Route-tab view.
729             if (ui->startRecPushButton->text() == "Stop recording")
730             {
731                 ui->labelRouteTabRecStatus->setText("Recorded " + QString::number(gpsData->roundCounter) + " point");
732             }
733
734             //Get speed. Route- and Measure-tab view.
735             gpsSpeed = location->getSpeed();
736
737             //Set speed. Route-tab view.
738             ui->labelRouteTabSpeed->setText("Speed:" + QString::number(gpsSpeed) + "km/h +/-" + QString::number(location->getEps()) + "km/h");
739
740             //Measure-tab view.
741             if (gpsSpeed < 40.0)
742             {              
743                 ui->labelMeasureTabSpeed->setText(QString::number(gpsSpeed)); //Set speed. //Measure-tab view.
744                 ui->labelMeasureTabTime->setText(QString::number(timeFromGps)); //Set time. //Measure-tab view.
745             }
746             //Measure-tab view.
747             else
748             {
749                 timer->stop(); //Measure timer
750                 ui->labelMeasureTabResult->setText(QString::number(timeFromGps));
751                 ui->labelMeasureTabResult->show();
752                 ui->pushButtonShowResultDialog->setEnabled(true);
753                 ui->pushButtonShowResultDialog->setEnabled(true);
754             }
755         }
756
757         //If GPS find less than 4 satellite.
758         else
759         {
760             ui->labelRouteTabGPSStatus->setText("GPS status: Waiting for GPS");
761             gpsTimer->stop();
762         }
763
764         gpsUpdateTime = 0;
765         gpsTimer->start(10);
766     }
767 }
768
769 /**
770   *This slot function is called when gps timer timeout(10ms).
771   */
772 void CarMainWindow::gpsTimerTimeout()
773 {
774     int time1000ms;
775     time1000ms += 10;
776
777     //IF time is 1 second
778     if (time1000ms == 1000)
779     {
780         //Calculate acceleration 1/s
781         gpsSpeedPrevious = gpsSpeedNow; //Previous speed
782         gpsSpeedNow = (location->getSpeed())/3.6; //Speed now (m/s)
783         gpsAcceleration = (gpsSpeedNow - gpsSpeedPrevious)/1; //Calculate acceleration: speed now - previous speed / 1s.
784         //Set acceleration. Route-tab view.
785         ui->labelRouteTabAcceleration->setText("Acceleration: " + QString::number( gpsAcceleration ) + " m/s2");
786     }
787
788     gpsUpdateTime++;
789     //Set GPS update time. Route-tab view.
790     ui->labelRouteTabGPSUpdateTime->setText("GPS update time: " + QString::number(gpsUpdateTime) + " ms");
791 }
792
793 /**
794   *This slot function is called when start rec push button clicked. Route-tab view.
795   */
796 void CarMainWindow::on_startRecPushButton_clicked()
797 {
798     //Start route recording.
799     if (ui->startRecPushButton->text() == "Start recording")
800     {
801         ui->startRecPushButton->setText("Stop recording");
802         ui->labelRouteTabRecStatus->setText("Recording started");
803         gpsData->startRouteRecording(ui->labelRouteTabGPSTime->text());
804     }
805
806     //Stop route recording.
807     else if (ui->startRecPushButton->text() == "Stop recording")
808     {
809         ui->startRecPushButton->setText("Start recording");
810         ui->labelRouteTabRecStatus->setText("Recording stopped");
811         gpsData->stopRouteRecording(ui->labelRouteTabGPSTime->text());
812     }
813 }
814
815 /**
816   *Sets time axis right way in result dialog and shows target speed result.
817   *@param double pTime is the target speed result time which is shown to the user.
818   */
819 void CarMainWindow::setTimeAxisGapAndShowResult(double pTime)
820 {
821     ui->pushButtonShowResultDialog->setEnabled(true);
822     ui->pushButtonSendResult->setEnabled(true);
823     QString timeInteger;
824     timeInteger.setNum(pTime);
825     ui->labelMeasureTabResult->show();
826     ui->labelMeasureTabResult->setText(timeInteger);
827
828     if (floor(pTime) <= 5)
829     {
830         result->setDiagramGapHorizontal(80);
831     }
832
833     else if (floor(pTime) <= 10)
834     {
835         result->setDiagramGapHorizontal(40);
836     }
837
838     else
839     {
840         result->setDiagramGapHorizontal(20);
841     }
842 }
843
844 void CarMainWindow::on_calibrateButton_clicked()
845 {
846     ui->autoStartButton->setEnabled(true);
847     ui->manualStartButton->setEnabled(true);
848
849     this->accelerometer->calibrate();
850 }