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 categorylist = 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 myRoute = new RouteDialog( this);
46 location = new Maemo5Location(this);
47 gpsData = new GPSData(location);
48 connect(location,SIGNAL(agnss()),this,SLOT(gpsStatus()));
49 gpsTime = new QDateTime();
56 accelerometer = new Accelerometer();
58 reverseAccelerationFlag = false;
59 vehicleStartedMoving = false;
63 accelerationStartThreshold = 0.02;
65 QTimer *accelerometerTimer = new QTimer(this);
66 connect(accelerometerTimer, SIGNAL(timeout()), this, SLOT(readAccelerometerData()));
67 accelerometerTimer->start(kAccelerometerSampleRate);
70 calculate = new Calculate();
71 //connect(calculate, SIGNAL(checkPointReached()), this, SLOT(handleCheckPoint()));
73 resetAccelerometerMeasurements();
75 measures = new Measures();
76 this->initializeMeasures();
78 timer->setInterval(300);
80 connect(this->timer, SIGNAL(timeout()), this, SLOT(after_timeout()));
81 connect(myLogin, SIGNAL( userNameChanged()), this, SLOT(updateUserName()));
83 ui->labelMeasureTabResult->hide();
85 this->setWindowTitle("Speed Freak");
90 *Destructor of this class. Deletes all dynamic objects and sets them to NULL.
92 CarMainWindow::~CarMainWindow()
100 delete welcomeDialog;
101 welcomeDialog = NULL;
111 *This function is used to .
114 void CarMainWindow::changeEvent(QEvent *e)
116 QMainWindow::changeEvent(e);
118 case QEvent::LanguageChange:
119 ui->retranslateUi(this);
127 *This slot function is called when ever list view is update. Start-tab view.
129 void CarMainWindow::on_listViewStartTabAccelerationCategories_clicked(QModelIndex index)
131 QString str = index.data().toString();
132 QStringList list = str.split("-");
133 QStringList list2 = list[1].split(" ");
135 ui->lineEditStartTabMin->setText(list[0]);
136 ui->lineEditStartTabMax->setText(list2[0]);
137 updateComboBoxStartTabUnits(list2[1]);
141 *This slot function is called when ever auto start button clicked. Start-tab view.
143 void CarMainWindow::on_autoStartButton_clicked()
145 choice = ui->listViewStartTabAccelerationCategories->currentIndex();
146 choiceInt = choice.row();
147 qDebug() << choiceInt;
150 ui->labelMeasureTabHeader->setText("Accelerate to 40 km/h");
151 result->setDiagramGapStem(75);
154 else if (choiceInt == 1)
156 ui->labelMeasureTabHeader->setText("Accelerate to 100 km/h");
157 result->setDiagramGapStem(30);
162 ui->labelMeasureTabHeader->setText("Accelerate to 80 km/h");
163 result->setDiagramGapStem(37.5);
165 ui->labelMeasureTabResult->setText("");
168 //measure = new MeasureDialog();
169 // connect(measure, SIGNAL(speedAchieved()), this, SLOT(openResultView()));
171 // Show measure dialog.
174 // TODO: Move next if else to the function which is called when target speed
178 if (floor(this->measures->getTime40kmh()) <= 5)
180 result->setDiagramGapHorizontal(80);
183 else if (floor(this->measures->getTime40kmh()) <= 10)
185 result->setDiagramGapHorizontal(40);
190 result->setDiagramGapHorizontal(20);
196 if (floor(this->measures->getTime40kmh()) <= 5)
198 result->setDiagramGapHorizontal(80);
201 else if (floor(this->measures->getTime40kmh()) <= 10)
203 result->setDiagramGapHorizontal(40);
208 result->setDiagramGapHorizontal(20);
212 ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
216 *This slot function is called when ever list view is update. Start-tab view.
217 *@param QString unit.
219 void CarMainWindow::updateComboBoxStartTabUnits(QString unit)
221 ui->comboBoxStartTabUnits->setCurrentIndex(ui->comboBoxStartTabUnits->findText(unit, Qt::MatchExactly));
225 *This function is used to init unit combobox. Start-tab view.
227 void CarMainWindow::initComboBoxStartTabUnits()
229 units << "km/h" << "km" << "h" << "m" << "min" << "Mile" << "Mph" << "in" << "ft" << "yrd";
230 ui->comboBoxStartTabUnits->addItems(units);
234 *This function is used to set items to unit combobox. Start-tab view.
235 *@param QStringlist units
237 void CarMainWindow::setComboBoxStartTabUnits(QStringList units)
239 ui->comboBoxStartTabUnits->addItems(units);
243 *This function is used to init listViewStartTabAccelerationCategories. Start-tab view.
245 void CarMainWindow::initListViewStartTabAccelerationCategories()
247 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";
248 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
249 ui->listViewStartTabAccelerationCategories->setModel(model);
253 *This function is used to set items to listViewStartTabAccelerationCategories. Start-tab view.
254 *@param QStringlist accelerationCategoriesStartTab
256 void CarMainWindow::setListViewStartTabAccelerationCategories(QStringList accelerationCategoriesStartTab)
258 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
259 ui->listViewStartTabAccelerationCategories->setModel(model);
263 *This function is used to set items to category combobox. Top-tab view.
266 void CarMainWindow::setCategoryCompoBox()
268 ui->comboBoxTopCategory->addItems(categorylist->getCategoryList());
272 *This function is used to set items to labelTopList. Top-tab view.
273 *@param QString category
275 void CarMainWindow::setListViewTopList(QString category, int size)
278 topList.append( categorylist->getTopList(category, size));
279 ui->labelTopList->setText(topList);
283 *This slot function is called when speed is achieved in measure dialog. Opens result dialog.
285 void CarMainWindow::openResultView()
287 //result->saveMeasuresToArray(measure->measures);
288 // Show result dialog.
290 ui->pushButtonSendResult->setEnabled(true);
294 if (floor(this->measures->getTime40kmh()) <= 5)
296 result->setDiagramGapHorizontal(80);
299 else if (floor(this->measures->getTime40kmh()) <= 10)
301 result->setDiagramGapHorizontal(40);
306 result->setDiagramGapHorizontal(20);
312 if (floor(this->measures->getTime40kmh()) <= 5)
314 result->setDiagramGapHorizontal(80);
317 else if (floor(this->measures->getTime40kmh()) <= 10)
319 result->setDiagramGapHorizontal(40);
324 result->setDiagramGapHorizontal(20);
327 timeInteger.setNum(this->measures->getTime40kmh());
328 //time = "0 - 40 km/h: ";
329 //time.append(timeInteger);
330 //ui->labelResult40kmh->setText(time);
331 ui->labelMeasureTabResult->show();
332 ui->labelMeasureTabResult->setText(timeInteger);
333 //ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
337 *This slot function is called when registrate button is clicked.
339 void CarMainWindow::on_registratePushButton_clicked()
341 myRegistration->show();
345 *This slot function is called when ever refresh button clicked. Top-tab view.
347 void CarMainWindow::on_buttonTopRefresh_clicked()
349 myHttpClient->requestCategories();
350 setCategoryCompoBox();
354 *This slot function is called when ever category combobox current index changed. Top-tab view.
355 *@param QString category
356 *@todo Check where limitNr is taken.
358 void CarMainWindow::on_comboBoxTopCategory_currentIndexChanged(QString category)
360 int limitNr = 5; //replace with real value?
361 QString limit = QString::number(limitNr);
362 category = "acceleration-0-100"; //replace with real value from category list/top window
363 myHttpClient->requestTopList(category, limit);
364 setListViewTopList(category,10);
368 *This slot function is called when ever category combobox activated. Top-tab view.
369 *@param QString category
371 void CarMainWindow::on_comboBoxTopCategory_activated(QString category)
373 setListViewTopList(category,10);
377 *This slot function is called when set/change user button is clicked.
379 void CarMainWindow::on_setUserPushButton_clicked()
385 *@brief Just for development, for the real button is not shown until
386 *measurin started and there are results.
387 *@todo Implement with real code and yet leave sendXml in the bottom in use.
389 void CarMainWindow::on_manualStartButton_clicked()
395 * This slot function is called when timer gives timeout signal. Checks current speed
396 * and stores times in measure class.
398 void CarMainWindow::after_timeout()
400 QString timeString, speedString;
404 if (floor(speed) == 10)
406 measures->setTime10kmh(time);
409 else if (floor(speed) == 20)
411 measures->setTime20kmh(time);
414 else if (floor(speed) == 30)
416 measures->setTime30kmh(time);
419 else if (floor(speed) == 40)
421 measures->setTime40kmh(time);
424 else if (floor(speed) == 50)
426 measures->setTime50kmh(time);
429 else if (floor(speed) == 60)
431 measures->setTime60kmh(time);
434 else if (floor(speed) == 70)
436 measures->setTime70kmh(time);
439 else if (floor(speed) == 80)
441 measures->setTime80kmh(time);
444 else if (floor(speed) == 90)
446 measures->setTime90kmh(time);
449 else if (floor(speed) == 100)
451 measures->setTime100kmh(time);
459 // If speed is over 40 km/h emits speedAchieved() signal and close this dialog.
465 //emit this->speedAchieved();
466 this->openResultView();
471 // Updates speed and time.
474 timeString.setNum(time);
475 speedString.setNum(speed);
476 ui->labelMeasureTabTime->setText(timeString);
477 ui->labelMeasureTabSpeed->setText(speedString);
485 * Initializes measures class's member variables.
487 void CarMainWindow::initializeMeasures()
489 measures->setTime10kmh(0);
490 measures->setTime20kmh(0);
491 measures->setTime30kmh(0);
492 measures->setTime40kmh(0);
493 measures->setTime50kmh(0);
494 measures->setTime60kmh(0);
495 measures->setTime70kmh(0);
496 measures->setTime80kmh(0);
497 measures->setTime90kmh(0);
498 measures->setTime100kmh(0);
502 * This slot function is called when Abort button is clicked.
504 void CarMainWindow::on_pushButtonMeasureTabAbort_clicked()
506 measures->setTime10kmh(0);
507 measures->setTime20kmh(0);
508 measures->setTime30kmh(0);
509 measures->setTime40kmh(0);
510 measures->setTime50kmh(0);
511 measures->setTime60kmh(0);
512 measures->setTime70kmh(0);
513 measures->setTime80kmh(0);
514 measures->setTime90kmh(0);
515 measures->setTime100kmh(0);
519 ui->tabWidget->setCurrentWidget(this->ui->StartTab);
523 void CarMainWindow::on_pushButtonSendResult_clicked()
525 myHttpClient->sendResultXml();
526 ui->pushButtonSendResult->setEnabled(false);
529 void CarMainWindow::updateUserName()
533 newUserName = myLogin->getUserName();
534 ui->userNameLabel->setText( "User: " + newUserName);
536 if (newUserName.length())
538 ui->setUserPushButton->setText( "Change User");
539 this->setWindowTitle("Speed freak - " + newUserName);
543 ui->setUserPushButton->setText( "Set User");
544 this->setWindowTitle("Speed freak");
548 void CarMainWindow::regUserToServer()
550 myHttpClient->requestRegistration();
554 void CarMainWindow::on_drawRoutePushButton_clicked()
560 * Opens result dialog when show result button is clicked.
561 * Sends measures as parameter to the resultdialogs saveMeasuresToArray-function.
563 void CarMainWindow::on_pushButtonShowResultDialog_clicked()
566 meas.setTime10kmh(1.3);
567 meas.setTime20kmh(2.5);
568 meas.setTime30kmh(3.6);
569 meas.setTime40kmh(6.7);
570 meas.setTime50kmh(7.3);
571 meas.setTime60kmh(7.5);
572 meas.setTime70kmh(8.6);
573 meas.setTime80kmh(8.7);
574 meas.setTime90kmh(9.6);
575 meas.setTime100kmh(9.9);
576 result->setDiagramGapHorizontal(40);
577 result->saveMeasuresToArray(&meas);
578 this->result->show();
581 void CarMainWindow::userLogin()
583 myHttpClient->checkLogin();
587 * Resets Accelerometer measurement variables
589 void CarMainWindow::resetAccelerometerMeasurements()
591 currentAcceleration = 0;
592 currentAccelerationString = "";
595 distanceTraveled = "";
596 firstAcceleration = 0;
599 //lastScreenUpdateInSeconds = 0;
601 reverseAccelerationFlag = false;
602 stopWatch.setHMS(0, 0, 0, 0);
603 //accelerometer->stop();
605 vehicleStartedMoving = false;
610 * This function is called to handle checkpoints
611 *@param totalTime total time elapsed since starting measurements
612 *@param currentSpeed current speed of the device
614 void CarMainWindow::handleCheckPoint(double totalTime, double currentSpeed)
623 *This function is called to read (and process) data from the accelerometer
625 void CarMainWindow::readAccelerometerData()
628 double changeInAcceleration = 0;
631 accelerometer->getAcceleration(x, y, z);
632 accelerometer->smoothData(x, y, z);
635 x -= accelerometer->getCalibrationX();
636 y -= accelerometer->getCalibrationY();
637 z -= accelerometer->getCalibrationZ();
639 QString str = QString("acc x: " + QString::number(x) + "\n" +
640 "acc y: " + QString::number(y) + "\n" +
641 "acc z: " + QString::number(z) + "\n");
643 if (!vehicleStartedMoving)
647 firstAcceleration = sqrt(x*x + y*y + z*z);
648 //firstAcceleration = y; // first read
653 currentAcceleration = sqrt(x*x + y*y + z*z);
654 changeInAcceleration = (currentAcceleration - firstAcceleration); // firstAcceleration only gets set once
656 if (((abs(changeInAcceleration) <= accelerationStartThreshold)
657 && !vehicleStartedMoving))
662 if (reverseAccelerationFlag)
664 // will be false until after 1st calculation
665 if ((changeInAcceleration <= 0))
667 // actually increasing here...
668 changeInAcceleration = abs(changeInAcceleration);
672 // actually decreasing here...
673 changeInAcceleration = (changeInAcceleration * -1);
676 if (!vehicleStartedMoving)
678 if ((changeInAcceleration < 0))
680 // we started to move backwards first time through
681 reverseAccelerationFlag = true;
682 changeInAcceleration = abs(changeInAcceleration);
684 vehicleStartedMoving = true;
686 stopWatch.setHMS(0, 0, 0, 0);
689 // keep the following line as close to the SetKinematicsProperties method as possible
690 currentTime = stopWatch.elapsed();
691 calculate->calculateParameters(changeInAcceleration, (currentTime - previousTime)/1000);
692 previousTime = currentTime;
694 s.sprintf("%.2f", changeInAcceleration);
695 currentAccelerationString = s;
698 speed = calculate->getCurrentSpeed();
699 speed = ((speed*1000)/kSecondsInHour);
700 s.sprintf("%.2f", speed);
703 s.sprintf("%.2f", calculate->getDistanceTraveled());
704 distanceTraveled = s;
710 time = calculate->getTotalTime();
712 s.sprintf("%.2f", time);
715 str.append("ca: " + currentAccelerationString + " G\n" );
716 str.append("cspeed: " + currentSpeed + " km/h \n" );
717 str.append("dist: " + distanceTraveled + " m \n" );
718 str.append("time: " + totalTime + " s \n" );
720 if ((stopTime > 0) && (previousTime >= stopTime))
722 // we want to end at a stopping point that the user chose
724 resetAccelerometerMeasurements();
729 *This function is used to calibrate accelerometer
731 void CarMainWindow::calibrateAccelerometer()
733 resetAccelerometerMeasurements();
734 accelerometer->calibrate();
738 *This slot function is called when GPS on checkbox state changed. Route-tab view.
741 void CarMainWindow::on_gpsOnCheckBox_stateChanged(int GPSState)
745 ui->labelRouteTabGPSStatus->setText("GPS off");//testing
746 location->stopPollingGPS();
750 ui->labelRouteTabGPSStatus->setText("GPS on");//testing
751 location->startPollingGPS();
756 *This slot function is called when GPS status changed. Route-tab view.
758 void CarMainWindow::gpsStatus()
760 if (ui->gpsOnCheckBox->isChecked())
762 if (location->getSatellitesInUse() >= 4)
765 ui->labelRouteTabGPSStatus->setText("GPS ready");
768 gpsTime->setTime_t(location->getTime());
769 ui->labelRouteTabGPSTime->setText(gpsTime->toString());
771 //Set latitude & longitude
772 ui->labelRouteTabLatitude->setText("Lat: " + QString::number(location->getLatitude()));
773 ui->labelRouteTabLongitude->setText("Lon: " + QString::number(location->getLongitude()));
778 ui->labelRouteTabGPSStatus->setText("Waiting for GPS");