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.
146 *@todo Check setDiagramGapStem(100) <- (choiceInt == 2)
148 void CarMainWindow::on_autoStartButton_clicked()
150 initializeMeasures();
151 resetAccelerometerMeasurements();
152 ui->pushButtonSendResult->setEnabled(false);
153 ui->pushButtonShowResultDialog->setEnabled(false);
154 choice = ui->listViewStartTabAccelerationCategories->currentIndex();
155 choiceInt = choice.row();
156 //qDebug() << "choiceInt" << choiceInt << " " << catList.at(choiceInt);
159 ui->labelMeasureTabHeader->setText("Accelerate to 40 km/h");
160 result->setDiagramGapStem(75);
162 else if (choiceInt == 1)
164 ui->labelMeasureTabHeader->setText("Accelerate to 100 km/h");
165 result->setDiagramGapStem(30);
167 else if (choiceInt == 2)
169 ui->labelMeasureTabHeader->setText("Accelerate to 10 km/h");
170 result->setDiagramGapStem(100);
174 ui->labelMeasureTabHeader->setText("Accelerate to 80 km/h");
175 result->setDiagramGapStem(37.5);
177 ui->labelMeasureTabResult->setText("");
179 this->accelerometerTimer->start(kAccelerometerSampleRate);
180 this->timer->start();
183 ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
187 *This slot function is called when ever list view is update. Start-tab view.
188 *@param QString unit.
190 void CarMainWindow::updateComboBoxStartTabUnits(QString unit)
192 ui->comboBoxStartTabUnits->setCurrentIndex(ui->comboBoxStartTabUnits->findText(unit, Qt::MatchExactly));
196 *This function is used to init unit combobox. Start-tab view.
198 void CarMainWindow::initComboBoxStartTabUnits()
200 units << "km/h" << "km" << "h" << "m" << "min" << "Mile" << "Mph" << "in" << "ft" << "yrd";
201 ui->comboBoxStartTabUnits->addItems(units);
205 *This function is used to set items to unit combobox. Start-tab view.
206 *@param QStringlist units
208 void CarMainWindow::setComboBoxStartTabUnits(QStringList units)
210 ui->comboBoxStartTabUnits->addItems(units);
214 *This function is used to init listViewStartTabAccelerationCategories. Start-tab view.
215 *@todo During development categories index values that are used for measuring are hardcoded
216 *@todo and accelerationCategoriesStartTab and catList are used instead of using
217 *@todo CategoryList::categoryList and CategoryList::cats.
219 void CarMainWindow::initListViewStartTabAccelerationCategories()
221 //Connect the user`s choice fron GUI to a correct variable name
222 catList.insert(0,"acceleration-0-40");
223 catList.insert(1,"acceleration-0-100");
224 catList.insert(2,"acceleration-0-10");
226 accelerationCategoriesStartTab << "0-40 km/h" << "0-100 km/h" << "0-10 km/h";
227 //<< "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";
228 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
229 ui->listViewStartTabAccelerationCategories->setModel(model);
233 *This function is used to set items to listViewStartTabAccelerationCategories. Start-tab view.
234 *@param QStringlist accelerationCategoriesStartTab
236 void CarMainWindow::setListViewStartTabAccelerationCategories(QStringList accelerationCategoriesStartTab)
238 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
239 ui->listViewStartTabAccelerationCategories->setModel(model);
242 void CarMainWindow::setLabelInfoToUser(QString infoText)
244 ui->labelInfoToUser->setText(infoText);
248 *This function is used to set items to category combobox. Top-tab view.
251 void CarMainWindow::setCategoryCompoBox()
253 qDebug() << "_setCategoryCompoBox";
254 ui->comboBoxTopCategory->addItems(myHttpClient->myXmlreader->myCategoryList->getCategoryList());
258 *This function prcesses UI updating after a new top10List has been received.
259 *@todo Check where limitNr is taken, fixed or user input, see on_comboBoxTopCategory_currentIndexChanged.
261 void CarMainWindow::showTop10()
264 setListViewTopList(recentCategory, limitNr);
268 *This function is used to set items to labelTopList. Top-tab view.
270 *@param Size, number of results.
272 void CarMainWindow::setListViewTopList(QString category, int size)
274 qDebug() << "_setListViewTopList";
276 topList.append(myHttpClient->myXmlreader->myCategoryList->getTopList(category, size));
277 ui->labelTopList->setText(topList);
281 *This slot function is called when speed is achieved in measure dialog. Opens result dialog.
283 void CarMainWindow::openResultView()
289 *This slot function is called when registrate button is clicked.
291 void CarMainWindow::on_registratePushButton_clicked()
293 myRegistration->show();
297 *This slot function is called when ever refresh button clicked. Top-tab view.
299 void CarMainWindow::on_buttonTopRefresh_clicked()
301 myHttpClient->requestCategories();
305 *This slot function is called when ever category combobox current index changed. Top-tab view.
306 *@param QString category.
307 *@todo Check where limitNr is taken, fixed or user input, see showTop10.
309 void CarMainWindow::on_comboBoxTopCategory_currentIndexChanged(QString category)
311 qDebug() << "_on_comboBoxTopCategory_currentIndexChanged: " << category;
312 recentCategory = category; //for showTop10()
314 QString limit = QString::number(limitNr);
315 myHttpClient->requestTopList(category, limit);
319 *This slot function is called when set/change user button is clicked.
321 void CarMainWindow::on_setUserPushButton_clicked()
327 *@brief Just for development, for the real button is not shown until
328 *measurin started and there are results.
329 *@todo Implement with real code and yet leave sendXml in the bottom in use.
331 void CarMainWindow::on_manualStartButton_clicked()
337 * This slot function is called when timer gives timeout signal. Checks current speed
338 * and stores times in measure class.
340 void CarMainWindow::after_timeout()
342 QString timeString, speedString;
345 timeString.setNum(time);
346 speedString.setNum(speed);
347 ui->labelMeasureTabTime->setText(timeString);
348 ui->labelMeasureTabSpeed->setText(speedString);
350 //handleCheckPoint(time, speed);
354 * Initializes measures class's member variables.
356 void CarMainWindow::initializeMeasures()
358 measures->setTime10kmh(0);
359 measures->setTime20kmh(0);
360 measures->setTime30kmh(0);
361 measures->setTime40kmh(0);
362 measures->setTime50kmh(0);
363 measures->setTime60kmh(0);
364 measures->setTime70kmh(0);
365 measures->setTime80kmh(0);
366 measures->setTime90kmh(0);
367 measures->setTime100kmh(0);
371 * This slot function is called when Abort button is clicked.
373 void CarMainWindow::on_pushButtonMeasureTabAbort_clicked()
375 ui->pushButtonSendResult->setEnabled(false);
376 ui->pushButtonShowResultDialog->setEnabled(false);
377 ui->labelMeasureTabResult->hide();
378 ui->labelMeasureTabTime->setText("");
379 ui->labelMeasureTabSpeed->setText("");
380 measures->setTime10kmh(0);
381 measures->setTime20kmh(0);
382 measures->setTime30kmh(0);
383 measures->setTime40kmh(0);
384 measures->setTime50kmh(0);
385 measures->setTime60kmh(0);
386 measures->setTime70kmh(0);
387 measures->setTime80kmh(0);
388 measures->setTime90kmh(0);
389 measures->setTime100kmh(0);
390 this->accelerometerTimer->stop();
394 ui->tabWidget->setCurrentWidget(this->ui->StartTab);
399 *This slot function is called when pushButtonSendResult is clicked.
400 *@todo Use real category value.
402 void CarMainWindow::on_pushButtonSendResult_clicked()
404 //Pick up relevant category name and pass it to the server
405 myHttpClient->sendResultXml(catList.at(choiceInt));
406 ui->pushButtonSendResult->setEnabled(false);
409 void CarMainWindow::updateUserName()
413 newUserName = myLogin->getUserName();
414 ui->userNameLabel->setText( "User: " + newUserName);
416 if (newUserName.length())
418 ui->setUserPushButton->setText( "Change User");
419 this->setWindowTitle("Speed Freak - " + newUserName);
423 ui->setUserPushButton->setText( "Set User");
424 this->setWindowTitle("Speed Freak");
428 void CarMainWindow::regUserToServer()
430 myHttpClient->requestRegistration();
434 void CarMainWindow::on_drawRoutePushButton_clicked()
436 QString routeFile = QString("route.txt");
437 if (myRoute->readRouteFromFile( routeFile) == true)
444 * Opens result dialog when show result button is clicked.
445 * Sends measures as parameter to the resultdialogs saveMeasuresToArray-function.
447 void CarMainWindow::on_pushButtonShowResultDialog_clicked()
449 result->saveMeasuresToArray(measures);
450 this->result->show();
453 void CarMainWindow::userLogin()
455 myHttpClient->checkLogin();
459 * Resets Accelerometer measurement variables
461 void CarMainWindow::resetAccelerometerMeasurements()
463 currentAcceleration = 0;
464 currentAccelerationString = "";
467 distanceTraveled = "";
468 firstAcceleration = 0;
471 //lastScreenUpdateInSeconds = 0;
473 reverseAccelerationFlag = false;
474 stopWatch.setHMS(0, 0, 0, 0);
475 //accelerometer->stop();
477 vehicleStartedMoving = false;
482 * This function is called to handle checkpoints
483 *@param totalTime total time elapsed since starting measurements
484 *@param currentSpeed current speed of the device
486 void CarMainWindow::handleCheckPoint(double totalTime, double currentSpeed)
488 switch (counterForSaveResults)
491 measures->setTime10kmh(totalTime);
495 measures->setTime20kmh(totalTime);
499 measures->setTime30kmh(totalTime);
503 measures->setTime40kmh(totalTime);
507 measures->setTime50kmh(totalTime);
511 measures->setTime60kmh(totalTime);
515 measures->setTime70kmh(totalTime);
519 measures->setTime80kmh(totalTime);
523 measures->setTime90kmh(totalTime);
527 measures->setTime100kmh(totalTime);
533 counterForSaveResults++;
535 if (choiceInt == 0 && measures->getTime40kmh() != 0)
537 setTimeAxisGapAndShowResult(measures->getTime40kmh());
539 this->accelerometerTimer->stop();
542 counterForSaveResults = 0;
544 else if (choiceInt == 1 && measures->getTime100kmh() != 0)
546 setTimeAxisGapAndShowResult(measures->getTime100kmh());
548 this->accelerometerTimer->stop();
551 counterForSaveResults = 0;
553 else if (choiceInt == 2 && measures->getTime10kmh() != 0)
555 setTimeAxisGapAndShowResult(measures->getTime10kmh());
557 this->accelerometerTimer->stop();
560 counterForSaveResults = 0;
562 else if (choiceInt != 1 && choiceInt != 0 && measures->getTime80kmh() != 0)
564 setTimeAxisGapAndShowResult(measures->getTime80kmh());
566 this->accelerometerTimer->stop();
569 counterForSaveResults = 0;
573 qDebug() << "something wrong in handleCheckPoint()";
578 *This function is called to read (and process) data from the accelerometer
580 void CarMainWindow::readAccelerometerData()
583 double changeInAcceleration = 0;
586 accelerometer->getAcceleration(x, y, z);
587 accelerometer->smoothData(x, y, z);
590 x -= accelerometer->getCalibrationX();
591 y -= accelerometer->getCalibrationY();
592 z -= accelerometer->getCalibrationZ();
594 QString str = QString("acc x: " + QString::number(x) + "\n" +
595 "acc y: " + QString::number(y) + "\n" +
596 "acc z: " + QString::number(z) + "\n");
598 if (!vehicleStartedMoving)
602 firstAcceleration = sqrt(x*x + y*y + z*z);
603 //firstAcceleration = y; // first read
608 currentAcceleration = sqrt(x*x + y*y + z*z);
609 changeInAcceleration = (currentAcceleration - firstAcceleration); // firstAcceleration only gets set once
611 if (((fabs(changeInAcceleration) <= accelerationStartThreshold)
612 && !vehicleStartedMoving))
617 if (reverseAccelerationFlag)
619 // will be false until after 1st calculation
620 if ((changeInAcceleration <= 0))
622 // actually increasing here...
623 changeInAcceleration = fabs(changeInAcceleration);
627 // actually decreasing here...
628 changeInAcceleration = (changeInAcceleration * -1);
631 if (!vehicleStartedMoving)
633 if ((changeInAcceleration < 0))
635 // we started to move backwards first time through
636 reverseAccelerationFlag = true;
637 changeInAcceleration = fabs(changeInAcceleration);
639 vehicleStartedMoving = true;
641 stopWatch.setHMS(0, 0, 0, 0);
644 // keep the following line as close to the SetKinematicsProperties method as possible
645 currentTime = stopWatch.elapsed();
646 calculate->calculateParameters(changeInAcceleration, (currentTime - previousTime)/1000);
647 previousTime = currentTime;
649 s.sprintf("%.2f", changeInAcceleration);
650 currentAccelerationString = s;
653 speed = calculate->getCurrentSpeed();
654 speed = ((speed*1000)/kSecondsInHour);
655 s.sprintf("%.2f", speed);
658 s.sprintf("%.2f", calculate->getDistanceTraveled());
659 distanceTraveled = s;
665 time = calculate->getTotalTime();
667 s.sprintf("%.2f", time);
670 str.append("ca: " + currentAccelerationString + " G\n" );
671 str.append("cspeed: " + currentSpeed + " km/h \n" );
672 str.append("dist: " + distanceTraveled + " m \n" );
673 str.append("time: " + totalTime + " s \n" );
675 if ((stopTime > 0) && (previousTime >= stopTime))
677 // we want to end at a stopping point that the user chose
679 resetAccelerometerMeasurements();
684 *This function is used to calibrate accelerometer
686 void CarMainWindow::calibrateAccelerometer()
688 resetAccelerometerMeasurements();
689 accelerometer->calibrate();
693 *This slot function is called when GPS on checkbox state changed. Route-tab view.
696 void CarMainWindow::on_gpsOnCheckBox_stateChanged(int GPSState)
700 ui->labelRouteTabGPSStatus->setText("GPS off");//testing
701 location->stopPollingGPS();
705 ui->labelRouteTabGPSStatus->setText("GPS on");//testing
706 location->startPollingGPS();
711 *This slot function is called when GPS status changed. Route-tab view.
713 void CarMainWindow::gpsStatus()
715 if (ui->gpsOnCheckBox->isChecked())
717 if (location->getSatellitesInUse() >= 4)
720 //ui->labelRouteTabGPSStatus->setText("GPS ready");
721 ui->labelRouteTabGPSStatus->setText(QString::number(gpsData->roundCounter));
724 gpsTime->setTime_t(location->getTime());
725 ui->labelRouteTabGPSTime->setText(gpsTime->toString());
727 //Set latitude & longitude
728 ui->labelRouteTabLatitude->setText("Lat: " + QString::number(location->getLatitude()));
729 ui->labelRouteTabLongitude->setText("Lon: " + QString::number(location->getLongitude()));
734 ui->labelRouteTabGPSStatus->setText("Waiting for GPS");
737 ui->labelRouteTabSpeed->setText(QString::number(location->getSpeed()));
740 void CarMainWindow::on_startRecPushButton_clicked()
742 ui->labelRouteTabRecStatus->setText("Recording started");
743 gpsData->startRouteRecording(ui->labelRouteTabGPSTime->text());
746 void CarMainWindow::on_stopRecPushButton_clicked()
748 ui->labelRouteTabRecStatus->setText("Recording stopped");
749 gpsData->stopRouteRecording(ui->labelRouteTabGPSTime->text());
753 *Sets time axis right way in result dialog and shows target speed result.
754 *@param double pTime is the target speed result time which is shown to the user.
756 void CarMainWindow::setTimeAxisGapAndShowResult(double pTime)
758 ui->pushButtonShowResultDialog->setEnabled(true);
759 ui->pushButtonSendResult->setEnabled(true);
761 timeInteger.setNum(pTime);
762 ui->labelMeasureTabResult->show();
763 ui->labelMeasureTabResult->setText(timeInteger);
765 if (floor(pTime) <= 5)
767 result->setDiagramGapHorizontal(80);
770 else if (floor(pTime) <= 10)
772 result->setDiagramGapHorizontal(40);
777 result->setDiagramGapHorizontal(20);