88f8af122451877f65bab5d334623a93d93c191a
[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     measures->initializeMembers();
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     measures->initializeMembers();
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 GPS checkbox is ON
363     if (ui->gpsOnCheckBox->isChecked())
364     {
365         if ( gpsSpeed > 1.0 )
366         {
367             timeFromGps += 0.1;
368         }
369     }
370
371     else
372     {
373         ui->labelMeasureTabSpeed->setText(QString::number(this->speed)); //Set speed. //Measure-tab view.
374         ui->labelMeasureTabTime->setText(QString::number(this->time)); //Set time. //Measure-tab view.
375     }
376 }
377
378 /**
379   * This slot function is called when Abort button is clicked.
380   */
381 void CarMainWindow::on_pushButtonMeasureTabAbort_clicked()
382 {
383     ui->pushButtonSendResult->setEnabled(false);
384     ui->pushButtonShowResultDialog->setEnabled(false);
385     ui->labelMeasureTabResult->hide();
386     ui->labelMeasureTabTime->setText("");
387     ui->labelMeasureTabSpeed->setText("");
388     measures->initializeMembers();
389     this->accelerometerTimer->stop();
390     this->timer->stop();
391     this->time = 0;
392     this->speed = 0;
393     ui->tabWidget->setCurrentWidget(this->ui->StartTab);
394     //this->close();
395
396     //GPS
397     gpsSpeed = 0.0;
398     timeFromGps = 0.0;
399 }
400
401 /**
402   *This slot function is called when pushButtonSendResult is clicked.
403   *@todo Use real category value.
404   */
405 void CarMainWindow::on_pushButtonSendResult_clicked()
406 {
407     //Pick up relevant category name and pass it to the server
408     myHttpClient->sendResultXml(catList.at(choiceInt));
409     ui->pushButtonSendResult->setEnabled(false);
410 }
411
412 void CarMainWindow::updateUserName()
413 {
414     QString newUserName;
415
416     newUserName = myLogin->getUserName();
417     ui->userNameLabel->setText( "User: " + newUserName);
418
419     if (newUserName.length())
420     {
421        ui->setUserPushButton->setText( "Change User");
422        this->setWindowTitle("Speed Freak - " + newUserName);
423     }
424     else
425     {
426         ui->setUserPushButton->setText( "Set User");
427         this->setWindowTitle("Speed Freak");
428     }
429 }
430
431 void CarMainWindow::regUserToServer()
432 {
433     myHttpClient->requestRegistration();
434 }
435
436
437 void CarMainWindow::on_drawRoutePushButton_clicked()
438 {
439     QString routeFile = QString("route.txt");
440     if (myRoute->readRouteFromFile( routeFile) == true)
441     {
442         myRoute->show();
443     }
444 }
445
446 /**
447   * Opens result dialog when show result button is clicked.
448   * Sends measures as parameter to the resultdialogs saveMeasuresToArray-function.
449   */
450 void CarMainWindow::on_pushButtonShowResultDialog_clicked()
451 {
452     result->saveMeasuresToArray(measures);
453     this->result->show();
454 }
455
456 void CarMainWindow::userLogin()
457 {
458     myHttpClient->checkLogin();
459 }
460
461 /**
462   * Resets Accelerometer measurement variables
463   */
464 void CarMainWindow::resetAccelerometerMeasurements()
465 {
466     currentAcceleration = 0;
467     currentAccelerationString = "";
468     currentSpeed = "";
469     currentTime = 0;
470     distanceTraveled = "";
471     //firstAcceleration = 0;
472     //horsepower = null;
473     isNewRun = true;
474     //lastScreenUpdateInSeconds = 0;
475     previousTime = 0;
476     reverseAccelerationFlag = false;
477     stopWatch.start();
478     //accelerometer->stop();
479     totalTime = "";
480     vehicleStartedMoving = false;
481     calculate->reset();
482 }
483
484 /**
485   * This function is called to handle checkpoints
486   *@param totalTime total time elapsed since starting measurements
487   *@param currentSpeed current speed of the device
488   */
489 void CarMainWindow::handleCheckPoint(double totalTime, double currentSpeed)
490 {
491     switch (counterForSaveResults)
492     {
493     case 0:
494         measures->setTime10kmh(totalTime);
495         break;
496
497     case 1:
498         measures->setTime20kmh(totalTime);
499         break;
500
501     case 2:
502         measures->setTime30kmh(totalTime);
503         break;
504
505     case 3:
506         measures->setTime40kmh(totalTime);
507         break;
508
509     case 4:
510         measures->setTime50kmh(totalTime);
511         break;
512
513     case 5:
514         measures->setTime60kmh(totalTime);
515         break;
516
517     case 6:
518         measures->setTime70kmh(totalTime);
519         break;
520
521     case 7:
522         measures->setTime80kmh(totalTime);
523         break;
524
525     case 8:
526         measures->setTime90kmh(totalTime);
527         break;
528
529     case 9:
530         measures->setTime100kmh(totalTime);
531         break;
532
533     default:
534         break;
535     }
536     counterForSaveResults++;
537
538     if (choiceInt == 0 && measures->getTime40kmh() != 0)
539     {
540         setTimeAxisGapAndShowResult(measures->getTime40kmh());
541         this->timer->stop();
542         this->accelerometerTimer->stop();
543         this->time = 0;
544         this->speed = 0;
545         counterForSaveResults = 0;
546     }
547     else if (choiceInt == 1 && measures->getTime100kmh() != 0)
548     {
549         setTimeAxisGapAndShowResult(measures->getTime100kmh());
550         this->timer->stop();
551         this->accelerometerTimer->stop();
552         this->time = 0;
553         this->speed = 0;
554         counterForSaveResults = 0;
555     }
556     else if (choiceInt == 2 && measures->getTime10kmh() != 0)
557     {
558         setTimeAxisGapAndShowResult(measures->getTime10kmh());
559         this->timer->stop();
560         this->accelerometerTimer->stop();
561         this->time = 0;
562         this->speed = 0;
563         counterForSaveResults = 0;
564     }
565     else if (choiceInt != 1 && choiceInt != 0 && measures->getTime80kmh() != 0)
566     {
567         setTimeAxisGapAndShowResult(measures->getTime80kmh());
568         this->timer->stop();
569         this->accelerometerTimer->stop();
570         this->time = 0;
571         this->speed = 0;
572         counterForSaveResults = 0;
573     }
574     else
575     {
576         qDebug() << "something wrong in handleCheckPoint()";
577     }
578 }
579
580 /**
581   *This function is called to read (and process) data from the accelerometer
582   */
583 void CarMainWindow::readAccelerometerData()
584 {
585     QString s;
586     double changeInAcceleration = 0;
587     qreal x, y, z;
588
589     accelerometer->getAcceleration(x, y, z);
590
591     //  keep the following line as close to the SetKinematicsProperties method as possible
592     currentTime = stopWatch.elapsed();
593
594     //accelerometer->smoothData(x, y, z);
595
596     // Apply calibration
597     x -= accelerometer->getCalibrationX();
598     y -= accelerometer->getCalibrationY();
599     z -= accelerometer->getCalibrationZ();
600
601     QString str = QString("acc x: " + QString::number(x) + "\n" +
602                           "acc y: " + QString::number(y) + "\n" +
603                           "acc z: " + QString::number(z) + "\n");
604
605     currentAcceleration = z;//sqrt(x*x + y*y + z*z);
606     changeInAcceleration = currentAcceleration;
607
608     if (((fabs(changeInAcceleration) <= accelerationStartThreshold)
609                 && !vehicleStartedMoving))
610     {
611         return;
612     }
613     else if(!vehicleStartedMoving)
614     {
615         vehicleStartedMoving = true;
616         stopWatch.start();
617         previousTime = 0;
618         currentTime = 0;
619     }
620
621     calculate->calculateParameters(changeInAcceleration, (currentTime - previousTime)/1000);
622     previousTime = currentTime;
623
624     s.sprintf("%.2f", changeInAcceleration);
625     currentAccelerationString = s;
626
627     speed = 0.0;
628     speed = calculate->getCurrentSpeed();
629     speed = speed*3.6;//((speed*1000)/kSecondsInHour);
630     s.sprintf("%.1f", speed);
631     currentSpeed = s;
632
633     s.sprintf("%.2f", calculate->getDistanceTraveled());
634     distanceTraveled = s;
635
636     // TODO
637     //distanceTraveled;
638     //horsepower;
639
640     time = calculate->getTotalTime();
641
642     s.sprintf("%.2f", time);
643     totalTime = s;
644
645     str.append("ca: " + currentAccelerationString + " G\n" );
646     str.append("cspeed: " + currentSpeed + " km/h \n" );
647     str.append("dist: " + distanceTraveled + " m \n" );
648     str.append("time: " + totalTime + " s \n" );
649
650     if ((stopTime > 0) && (previousTime >= stopTime))
651     {
652         // we want to end at a stopping point that the user chose
653         // output results
654         resetAccelerometerMeasurements();
655     }
656 }
657
658 /**
659   *This function is used to calibrate accelerometer
660   */
661 void CarMainWindow::calibrateAccelerometer()
662 {
663     resetAccelerometerMeasurements();
664     accelerometer->calibrate();
665 }
666
667 /**
668   *This slot function is called when GPS on checkbox state changed. Route-tab view.
669   *@param int GPSState
670   */
671 void CarMainWindow::on_gpsOnCheckBox_stateChanged(int GPSState)
672 {
673     //Stop polling GPS. Route-tab view.
674     if (GPSState == 0)
675     {
676         ui->labelRouteTabGPSStatus->setText("GPS status: GPS off");
677         location->stopPollingGPS();
678         gpsUpdateTime = 0;
679         gpsTimer->stop();
680     }
681     //Start polling GPS. Route-tab view.
682     else
683     {
684         ui->labelRouteTabGPSStatus->setText("GPS status: GPS on");
685         location->startPollingGPS();
686     }
687 }
688
689 /**
690   *This slot function is called when GPS status changed. Route- and measure-tab view.
691   */
692 void CarMainWindow::gpsStatus()
693 {
694     //IF GPS checkbox is ON
695     if (ui->gpsOnCheckBox->isChecked())
696     {
697         //If GPS find 4 satellite.
698         if (location->getSatellitesInUse() >= 4)
699         {
700             //Set gps status. Route-tab view.
701             ui->labelRouteTabGPSStatus->setText("GPS ready");
702
703             //Set time. Route-tab view.
704             gpsTime->setTime_t(location->getTime());
705             QString gpsDateNow = gpsTime->toString("dd.MM.yyyy hh:mm:ss");
706             ui->labelRouteTabGPSTime->setText("GPS time: " + gpsDateNow);
707
708             //Set latitude & longitude. Route-tab view.
709             ui->labelRouteTabLatitude->setText("Latitude: " + QString::number(location->getLatitude()));
710             ui->labelRouteTabLongitude->setText("Longitude: " + QString::number(location->getLongitude()));
711
712             //Set rec status. Route-tab view.
713             if (ui->startRecPushButton->text() == "Stop recording")
714             {
715                 ui->labelRouteTabRecStatus->setText("Recorded " + QString::number(gpsData->roundCounter) + " point");
716             }
717
718             //Get speed. Route- and Measure-tab view.
719             gpsSpeed = location->getSpeed();
720
721             //Set speed. Route-tab view.
722             ui->labelRouteTabSpeed->setText("Speed:" + QString::number(gpsSpeed) + "km/h +/-" + QString::number(location->getEps()) + "km/h");
723
724             //Measure-tab view.
725             if (gpsSpeed < 40.0)
726             {              
727                 ui->labelMeasureTabSpeed->setText(QString::number(gpsSpeed)); //Set speed. //Measure-tab view.
728                 ui->labelMeasureTabTime->setText(QString::number(timeFromGps)); //Set time. //Measure-tab view.
729             }
730             //Measure-tab view.
731             else
732             {
733                 timer->stop(); //Measure timer
734                 ui->labelMeasureTabResult->setText(QString::number(timeFromGps));
735                 ui->labelMeasureTabResult->show();
736                 ui->pushButtonShowResultDialog->setEnabled(true);
737                 ui->pushButtonShowResultDialog->setEnabled(true);
738             }
739         }
740
741         //If GPS find less than 4 satellite.
742         else
743         {
744             ui->labelRouteTabGPSStatus->setText("GPS status: Waiting for GPS");
745             gpsTimer->stop();
746         }
747
748         gpsUpdateTime = 0;
749         gpsTimer->start(10);
750     }
751 }
752
753 /**
754   *This slot function is called when gps timer timeout(10ms).
755   */
756 void CarMainWindow::gpsTimerTimeout()
757 {
758     int time1000ms;
759     time1000ms += 10;
760
761     //IF time is 1 second
762     if (time1000ms == 1000)
763     {
764         //Calculate acceleration 1/s
765         gpsSpeedPrevious = gpsSpeedNow; //Previous speed
766         gpsSpeedNow = (location->getSpeed())/3.6; //Speed now (m/s)
767         gpsAcceleration = (gpsSpeedNow - gpsSpeedPrevious)/1; //Calculate acceleration: speed now - previous speed / 1s.
768         //Set acceleration. Route-tab view.
769         ui->labelRouteTabAcceleration->setText("Acceleration: " + QString::number( gpsAcceleration ) + " m/s2");
770     }
771
772     gpsUpdateTime++;
773     //Set GPS update time. Route-tab view.
774     ui->labelRouteTabGPSUpdateTime->setText("GPS update time: " + QString::number(gpsUpdateTime) + " ms");
775 }
776
777 /**
778   *This slot function is called when start rec push button clicked. Route-tab view.
779   */
780 void CarMainWindow::on_startRecPushButton_clicked()
781 {
782     //Start route recording.
783     if (ui->startRecPushButton->text() == "Start recording")
784     {
785         ui->startRecPushButton->setText("Stop recording");
786         ui->labelRouteTabRecStatus->setText("Recording started");
787         gpsData->startRouteRecording(ui->labelRouteTabGPSTime->text());
788     }
789
790     //Stop route recording.
791     else if (ui->startRecPushButton->text() == "Stop recording")
792     {
793         ui->startRecPushButton->setText("Start recording");
794         ui->labelRouteTabRecStatus->setText("Recording stopped");
795         gpsData->stopRouteRecording(ui->labelRouteTabGPSTime->text());
796     }
797 }
798
799 /**
800   *Sets time axis right way in result dialog and shows target speed result.
801   *@param double pTime is the target speed result time which is shown to the user.
802   */
803 void CarMainWindow::setTimeAxisGapAndShowResult(double pTime)
804 {
805     ui->pushButtonShowResultDialog->setEnabled(true);
806     ui->pushButtonSendResult->setEnabled(true);
807     QString timeInteger;
808     timeInteger.setNum(pTime);
809     ui->labelMeasureTabResult->show();
810     ui->labelMeasureTabResult->setText(timeInteger);
811
812     if (floor(pTime) <= 5)
813     {
814         result->setDiagramGapHorizontal(80);
815     }
816
817     else if (floor(pTime) <= 10)
818     {
819         result->setDiagramGapHorizontal(40);
820     }
821
822     else
823     {
824         result->setDiagramGapHorizontal(20);
825     }
826 }
827
828 void CarMainWindow::on_calibrateButton_clicked()
829 {
830     ui->autoStartButton->setEnabled(true);
831     ui->manualStartButton->setEnabled(true);
832
833     this->accelerometer->calibrate();
834 }