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