2 * CarMainWindow main class
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
14 #include "carmainwindow.h"
17 #define kAccelerometerSampleRate 50
18 #define kFilteringFactor 0.2
19 #define kSecondsInHour 3600
22 *Constructor of this class.
23 *@param QWidget pointer to parent object. By default the value is NULL.
25 CarMainWindow::CarMainWindow(QWidget *parent):QMainWindow(parent), ui(new Ui::CarMainWindow)
28 ui->tabWidget->setCurrentWidget(this->ui->StartTab);
29 result = new ResultDialog();
30 //measure = new MeasureDialog();
31 welcomeDialog = new WelcomeDialog();
32 welcomeDialog->show();
34 initComboBoxStartTabUnits();
35 initListViewStartTabAccelerationCategories();
37 myLogin = new LoginWindow(this);
38 myCategorylist = new CategoryList();
39 myHttpClient = new HttpClient(this);
40 myRegistration = new Registration(this);
41 connect(myRegistration,SIGNAL(sendregistration()),this,SLOT(regUserToServer()));
42 connect(myLogin,SIGNAL(userNameChanged()),this,SLOT(userLogin()));
43 connect(myHttpClient->myXmlreader, SIGNAL(receivedCategoryList()), this, SLOT(setCategoryCompoBox()));
44 connect(myHttpClient->myXmlreader, SIGNAL(receivedTop10List()), this, SLOT(showTop10()));
45 myRoute = new RouteDialog( this);
48 location = new Maemo5Location(this);
49 gpsData = new GPSData(location);
50 connect(location,SIGNAL(agnss()),this,SLOT(gpsStatus()));
51 gpsTime = new QDateTime();
55 counterForSaveResults = 0;
59 accelerometer = new Accelerometer();
61 reverseAccelerationFlag = false;
62 vehicleStartedMoving = false;
66 accelerationStartThreshold = 0.02;
68 accelerometerTimer = new QTimer(this);
69 connect(accelerometerTimer, SIGNAL(timeout()), this, SLOT(readAccelerometerData()));
70 //accelerometerTimer->start(kAccelerometerSampleRate);
73 calculate = new Calculate();
74 connect(calculate, SIGNAL(checkPointReached()), this, SLOT(handleCheckPoint()));
76 resetAccelerometerMeasurements();
78 measures = new Measures();
79 this->initializeMeasures();
81 this->timer->setInterval(300);
83 connect(this->timer, SIGNAL(timeout()), this, SLOT(after_timeout()));
84 connect(myLogin, SIGNAL( userNameChanged()), this, SLOT(updateUserName()));
86 ui->labelMeasureTabResult->hide();
87 ui->pushButtonShowResultDialog->setEnabled(false);
89 this->setWindowTitle("Speed Freak");
94 *Destructor of this class. Deletes all dynamic objects and sets them to NULL.
96 CarMainWindow::~CarMainWindow()
102 delete myCategorylist;
103 myCategorylist = NULL;
104 delete welcomeDialog;
105 welcomeDialog = NULL;
115 *This function is used to .
118 void CarMainWindow::changeEvent(QEvent *e)
120 QMainWindow::changeEvent(e);
122 case QEvent::LanguageChange:
123 ui->retranslateUi(this);
131 *This slot function is called when ever list view is update. Start-tab view.
133 void CarMainWindow::on_listViewStartTabAccelerationCategories_clicked(QModelIndex index)
135 QString str = index.data().toString();
136 QStringList list = str.split("-");
137 QStringList list2 = list[1].split(" ");
139 ui->lineEditStartTabMin->setText(list[0]);
140 ui->lineEditStartTabMax->setText(list2[0]);
141 updateComboBoxStartTabUnits(list2[1]);
145 *This slot function is called when ever auto start button clicked. Start-tab view.
147 void CarMainWindow::on_autoStartButton_clicked()
149 initializeMeasures();
150 resetAccelerometerMeasurements();
151 ui->pushButtonSendResult->setEnabled(false);
152 ui->pushButtonShowResultDialog->setEnabled(false);
153 choice = ui->listViewStartTabAccelerationCategories->currentIndex();
154 choiceInt = choice.row();
155 qDebug() << choiceInt;
158 ui->labelMeasureTabHeader->setText("Accelerate to 40 km/h");
159 result->setDiagramGapStem(75);
162 else if (choiceInt == 1)
164 ui->labelMeasureTabHeader->setText("Accelerate to 100 km/h");
165 result->setDiagramGapStem(30);
170 ui->labelMeasureTabHeader->setText("Accelerate to 80 km/h");
171 result->setDiagramGapStem(37.5);
173 ui->labelMeasureTabResult->setText("");
175 this->accelerometerTimer->start(kAccelerometerSampleRate);
176 this->timer->start();
179 ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
183 *This slot function is called when ever list view is update. Start-tab view.
184 *@param QString unit.
186 void CarMainWindow::updateComboBoxStartTabUnits(QString unit)
188 ui->comboBoxStartTabUnits->setCurrentIndex(ui->comboBoxStartTabUnits->findText(unit, Qt::MatchExactly));
192 *This function is used to init unit combobox. Start-tab view.
194 void CarMainWindow::initComboBoxStartTabUnits()
196 units << "km/h" << "km" << "h" << "m" << "min" << "Mile" << "Mph" << "in" << "ft" << "yrd";
197 ui->comboBoxStartTabUnits->addItems(units);
201 *This function is used to set items to unit combobox. Start-tab view.
202 *@param QStringlist units
204 void CarMainWindow::setComboBoxStartTabUnits(QStringList units)
206 ui->comboBoxStartTabUnits->addItems(units);
210 *This function is used to init listViewStartTabAccelerationCategories. Start-tab view.
212 void CarMainWindow::initListViewStartTabAccelerationCategories()
214 accelerationCategoriesStartTab << "0-40 km/h" << "0-100 km/h"; //<< "0-1/4 Mile" << "0-1/8 Mile" << "0-50 km" << "50-100 Mile" << "0-60 Mph" << "0-100 m" << "0-50 ft" << "0-50 yrd" << "0-500 in";
215 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
216 ui->listViewStartTabAccelerationCategories->setModel(model);
220 *This function is used to set items to listViewStartTabAccelerationCategories. Start-tab view.
221 *@param QStringlist accelerationCategoriesStartTab
223 void CarMainWindow::setListViewStartTabAccelerationCategories(QStringList accelerationCategoriesStartTab)
225 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
226 ui->listViewStartTabAccelerationCategories->setModel(model);
230 *This function is used to set items to category combobox. Top-tab view.
233 void CarMainWindow::setCategoryCompoBox()
235 qDebug() << "_setCategoryCompoBox";
236 ui->comboBoxTopCategory->addItems(myHttpClient->myXmlreader->myCategoryList->getCategoryList());
240 *This function prcesses UI updating after a new top10List has been received.
241 *@todo Check where limitNr is taken, fixed or user input, see on_comboBoxTopCategory_currentIndexChanged.
243 void CarMainWindow::showTop10()
246 setListViewTopList(recentCategory, limitNr);
250 *This function is used to set items to labelTopList. Top-tab view.
252 *@param Size, number of results.
254 void CarMainWindow::setListViewTopList(QString category, int size)
256 qDebug() << "_setListViewTopList";
258 topList.append(myHttpClient->myXmlreader->myCategoryList->getTopList(category, size));
259 ui->labelTopList->setText(topList);
263 *This slot function is called when speed is achieved in measure dialog. Opens result dialog.
265 void CarMainWindow::openResultView()
271 *This slot function is called when registrate button is clicked.
273 void CarMainWindow::on_registratePushButton_clicked()
275 myRegistration->show();
279 *This slot function is called when ever refresh button clicked. Top-tab view.
281 void CarMainWindow::on_buttonTopRefresh_clicked()
283 myHttpClient->requestCategories();
287 *This slot function is called when ever category combobox current index changed. Top-tab view.
288 *@param QString category.
289 *@todo Check where limitNr is taken, fixed or user input, see showTop10.
291 void CarMainWindow::on_comboBoxTopCategory_currentIndexChanged(QString category)
293 qDebug() << "_on_comboBoxTopCategory_currentIndexChanged: " << category;
294 recentCategory = category; //for showTop10()
296 QString limit = QString::number(limitNr);
297 myHttpClient->requestTopList(category, limit);
301 *This slot function is called when set/change user button is clicked.
303 void CarMainWindow::on_setUserPushButton_clicked()
309 *@brief Just for development, for the real button is not shown until
310 *measurin started and there are results.
311 *@todo Implement with real code and yet leave sendXml in the bottom in use.
313 void CarMainWindow::on_manualStartButton_clicked()
319 * This slot function is called when timer gives timeout signal. Checks current speed
320 * and stores times in measure class.
322 void CarMainWindow::after_timeout()
324 QString timeString, speedString;
327 timeString.setNum(time);
328 speedString.setNum(speed);
329 ui->labelMeasureTabTime->setText(timeString);
330 ui->labelMeasureTabSpeed->setText(speedString);
332 //handleCheckPoint(time, speed);
336 * Initializes measures class's member variables.
338 void CarMainWindow::initializeMeasures()
340 measures->setTime10kmh(0);
341 measures->setTime20kmh(0);
342 measures->setTime30kmh(0);
343 measures->setTime40kmh(0);
344 measures->setTime50kmh(0);
345 measures->setTime60kmh(0);
346 measures->setTime70kmh(0);
347 measures->setTime80kmh(0);
348 measures->setTime90kmh(0);
349 measures->setTime100kmh(0);
353 * This slot function is called when Abort button is clicked.
355 void CarMainWindow::on_pushButtonMeasureTabAbort_clicked()
357 ui->pushButtonSendResult->setEnabled(false);
358 ui->pushButtonShowResultDialog->setEnabled(false);
359 ui->labelMeasureTabResult->hide();
360 ui->labelMeasureTabTime->setText("");
361 ui->labelMeasureTabSpeed->setText("");
362 measures->setTime10kmh(0);
363 measures->setTime20kmh(0);
364 measures->setTime30kmh(0);
365 measures->setTime40kmh(0);
366 measures->setTime50kmh(0);
367 measures->setTime60kmh(0);
368 measures->setTime70kmh(0);
369 measures->setTime80kmh(0);
370 measures->setTime90kmh(0);
371 measures->setTime100kmh(0);
372 this->accelerometerTimer->stop();
376 ui->tabWidget->setCurrentWidget(this->ui->StartTab);
381 *This slot function is called when pushButtonSendResult is clicked.
382 *@todo Use real category value.
384 void CarMainWindow::on_pushButtonSendResult_clicked()
386 myHttpClient->sendResultXml("acceleration-0-100");
387 ui->pushButtonSendResult->setEnabled(false);
390 void CarMainWindow::updateUserName()
394 newUserName = myLogin->getUserName();
395 ui->userNameLabel->setText( "User: " + newUserName);
397 if (newUserName.length())
399 ui->setUserPushButton->setText( "Change User");
400 this->setWindowTitle("Speed Freak - " + newUserName);
404 ui->setUserPushButton->setText( "Set User");
405 this->setWindowTitle("Speed Freak");
409 void CarMainWindow::regUserToServer()
411 myHttpClient->requestRegistration();
415 void CarMainWindow::on_drawRoutePushButton_clicked()
421 * Opens result dialog when show result button is clicked.
422 * Sends measures as parameter to the resultdialogs saveMeasuresToArray-function.
424 void CarMainWindow::on_pushButtonShowResultDialog_clicked()
426 result->saveMeasuresToArray(measures);
427 this->result->show();
430 void CarMainWindow::userLogin()
432 myHttpClient->checkLogin();
436 * Resets Accelerometer measurement variables
438 void CarMainWindow::resetAccelerometerMeasurements()
440 currentAcceleration = 0;
441 currentAccelerationString = "";
444 distanceTraveled = "";
445 firstAcceleration = 0;
448 //lastScreenUpdateInSeconds = 0;
450 reverseAccelerationFlag = false;
451 stopWatch.setHMS(0, 0, 0, 0);
452 //accelerometer->stop();
454 vehicleStartedMoving = false;
459 * This function is called to handle checkpoints
460 *@param totalTime total time elapsed since starting measurements
461 *@param currentSpeed current speed of the device
463 void CarMainWindow::handleCheckPoint(double totalTime, double currentSpeed)
465 switch (counterForSaveResults)
468 measures->setTime10kmh(totalTime);
472 measures->setTime20kmh(totalTime);
476 measures->setTime30kmh(totalTime);
480 measures->setTime40kmh(totalTime);
484 measures->setTime50kmh(totalTime);
488 measures->setTime60kmh(totalTime);
492 measures->setTime70kmh(totalTime);
496 measures->setTime80kmh(totalTime);
500 measures->setTime90kmh(totalTime);
504 measures->setTime100kmh(totalTime);
510 counterForSaveResults++;
512 if (choiceInt == 0 && measures->getTime40kmh() != 0)
514 setTimeAxisGapAndShowResult(measures->getTime40kmh());
516 this->accelerometerTimer->stop();
519 counterForSaveResults = 0;
522 else if (choiceInt == 1 && measures->getTime100kmh() != 0)
524 setTimeAxisGapAndShowResult(measures->getTime100kmh());
526 this->accelerometerTimer->stop();
529 counterForSaveResults = 0;
533 else if (choiceInt != 1 && choiceInt != 0 && measures->getTime80kmh() != 0)
535 setTimeAxisGapAndShowResult(measures->getTime80kmh());
537 this->accelerometerTimer->stop();
540 counterForSaveResults = 0;
550 *This function is called to read (and process) data from the accelerometer
552 void CarMainWindow::readAccelerometerData()
555 double changeInAcceleration = 0;
558 accelerometer->getAcceleration(x, y, z);
559 accelerometer->smoothData(x, y, z);
562 x -= accelerometer->getCalibrationX();
563 y -= accelerometer->getCalibrationY();
564 z -= accelerometer->getCalibrationZ();
566 QString str = QString("acc x: " + QString::number(x) + "\n" +
567 "acc y: " + QString::number(y) + "\n" +
568 "acc z: " + QString::number(z) + "\n");
570 if (!vehicleStartedMoving)
574 firstAcceleration = sqrt(x*x + y*y + z*z);
575 //firstAcceleration = y; // first read
580 currentAcceleration = sqrt(x*x + y*y + z*z);
581 changeInAcceleration = (currentAcceleration - firstAcceleration); // firstAcceleration only gets set once
583 if (((fabs(changeInAcceleration) <= accelerationStartThreshold)
584 && !vehicleStartedMoving))
589 if (reverseAccelerationFlag)
591 // will be false until after 1st calculation
592 if ((changeInAcceleration <= 0))
594 // actually increasing here...
595 changeInAcceleration = fabs(changeInAcceleration);
599 // actually decreasing here...
600 changeInAcceleration = (changeInAcceleration * -1);
603 if (!vehicleStartedMoving)
605 if ((changeInAcceleration < 0))
607 // we started to move backwards first time through
608 reverseAccelerationFlag = true;
609 changeInAcceleration = fabs(changeInAcceleration);
611 vehicleStartedMoving = true;
613 stopWatch.setHMS(0, 0, 0, 0);
616 // keep the following line as close to the SetKinematicsProperties method as possible
617 currentTime = stopWatch.elapsed();
618 calculate->calculateParameters(changeInAcceleration, (currentTime - previousTime)/1000);
619 previousTime = currentTime;
621 s.sprintf("%.2f", changeInAcceleration);
622 currentAccelerationString = s;
625 speed = calculate->getCurrentSpeed();
626 speed = ((speed*1000)/kSecondsInHour);
627 s.sprintf("%.2f", speed);
630 s.sprintf("%.2f", calculate->getDistanceTraveled());
631 distanceTraveled = s;
637 time = calculate->getTotalTime();
639 s.sprintf("%.2f", time);
642 str.append("ca: " + currentAccelerationString + " G\n" );
643 str.append("cspeed: " + currentSpeed + " km/h \n" );
644 str.append("dist: " + distanceTraveled + " m \n" );
645 str.append("time: " + totalTime + " s \n" );
647 if ((stopTime > 0) && (previousTime >= stopTime))
649 // we want to end at a stopping point that the user chose
651 resetAccelerometerMeasurements();
656 *This function is used to calibrate accelerometer
658 void CarMainWindow::calibrateAccelerometer()
660 resetAccelerometerMeasurements();
661 accelerometer->calibrate();
665 *This slot function is called when GPS on checkbox state changed. Route-tab view.
668 void CarMainWindow::on_gpsOnCheckBox_stateChanged(int GPSState)
672 ui->labelRouteTabGPSStatus->setText("GPS off");//testing
673 location->stopPollingGPS();
677 ui->labelRouteTabGPSStatus->setText("GPS on");//testing
678 location->startPollingGPS();
683 *This slot function is called when GPS status changed. Route-tab view.
685 void CarMainWindow::gpsStatus()
687 if (ui->gpsOnCheckBox->isChecked())
689 if (location->getSatellitesInUse() >= 4)
692 //ui->labelRouteTabGPSStatus->setText("GPS ready");
693 ui->labelRouteTabGPSStatus->setText(QString::number(gpsData->roundCounter));
696 gpsTime->setTime_t(location->getTime());
697 ui->labelRouteTabGPSTime->setText(gpsTime->toString());
699 //Set latitude & longitude
700 ui->labelRouteTabLatitude->setText("Lat: " + QString::number(location->getLatitude()));
701 ui->labelRouteTabLongitude->setText("Lon: " + QString::number(location->getLongitude()));
706 ui->labelRouteTabGPSStatus->setText("Waiting for GPS");
709 ui->labelRouteTabSpeed->setText(QString::number(location->getSpeed()));
712 void CarMainWindow::on_startRecPushButton_clicked()
714 ui->labelRouteTabRecStatus->setText("Recording started");
715 gpsData->startRouteRecording(ui->labelRouteTabGPSTime->text());
718 void CarMainWindow::on_stopRecPushButton_clicked()
720 ui->labelRouteTabRecStatus->setText("Recording stopped");
721 gpsData->stopRouteRecording(ui->labelRouteTabGPSTime->text());
725 *Sets time axis right way in result dialog and shows target speed result.
726 *@param double pTime is the target speed result time which is shown to the user.
728 void CarMainWindow::setTimeAxisGapAndShowResult(double pTime)
730 ui->pushButtonShowResultDialog->setEnabled(true);
731 ui->pushButtonSendResult->setEnabled(true);
733 timeInteger.setNum(pTime);
734 ui->labelMeasureTabResult->show();
735 ui->labelMeasureTabResult->setText(timeInteger);
737 if (floor(pTime) <= 5)
739 result->setDiagramGapHorizontal(80);
742 else if (floor(pTime) <= 10)
744 result->setDiagramGapHorizontal(40);
749 result->setDiagramGapHorizontal(20);