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