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();
53 counterForSaveResults = 0;
57 accelerometer = new Accelerometer();
59 reverseAccelerationFlag = false;
60 vehicleStartedMoving = false;
64 accelerationStartThreshold = 0.02;
66 QTimer *accelerometerTimer = new QTimer(this);
67 connect(accelerometerTimer, SIGNAL(timeout()), this, SLOT(readAccelerometerData()));
68 accelerometerTimer->start(kAccelerometerSampleRate);
71 calculate = new Calculate();
72 connect(calculate, SIGNAL(checkPointReached()), this, SLOT(handleCheckPoint()));
74 resetAccelerometerMeasurements();
76 measures = new Measures();
77 this->initializeMeasures();
79 timer->setInterval(300);
81 connect(this->timer, SIGNAL(timeout()), this, SLOT(after_timeout()));
82 connect(myLogin, SIGNAL( userNameChanged()), this, SLOT(updateUserName()));
84 ui->labelMeasureTabResult->hide();
85 ui->pushButtonShowResultDialog->setEnabled(false);
87 this->setWindowTitle("Speed Freak");
92 *Destructor of this class. Deletes all dynamic objects and sets them to NULL.
94 CarMainWindow::~CarMainWindow()
102 delete welcomeDialog;
103 welcomeDialog = NULL;
113 *This function is used to .
116 void CarMainWindow::changeEvent(QEvent *e)
118 QMainWindow::changeEvent(e);
120 case QEvent::LanguageChange:
121 ui->retranslateUi(this);
129 *This slot function is called when ever list view is update. Start-tab view.
131 void CarMainWindow::on_listViewStartTabAccelerationCategories_clicked(QModelIndex index)
133 QString str = index.data().toString();
134 QStringList list = str.split("-");
135 QStringList list2 = list[1].split(" ");
137 ui->lineEditStartTabMin->setText(list[0]);
138 ui->lineEditStartTabMax->setText(list2[0]);
139 updateComboBoxStartTabUnits(list2[1]);
143 *This slot function is called when ever auto start button clicked. Start-tab view.
145 void CarMainWindow::on_autoStartButton_clicked()
147 initializeMeasures();
148 ui->pushButtonShowResultDialog->setEnabled(false);
149 choice = ui->listViewStartTabAccelerationCategories->currentIndex();
150 choiceInt = choice.row();
151 qDebug() << choiceInt;
154 ui->labelMeasureTabHeader->setText("Accelerate to 40 km/h");
155 result->setDiagramGapStem(75);
158 else if (choiceInt == 1)
160 ui->labelMeasureTabHeader->setText("Accelerate to 100 km/h");
161 result->setDiagramGapStem(30);
166 ui->labelMeasureTabHeader->setText("Accelerate to 80 km/h");
167 result->setDiagramGapStem(37.5);
169 ui->labelMeasureTabResult->setText("");
174 ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
178 *This slot function is called when ever list view is update. Start-tab view.
179 *@param QString unit.
181 void CarMainWindow::updateComboBoxStartTabUnits(QString unit)
183 ui->comboBoxStartTabUnits->setCurrentIndex(ui->comboBoxStartTabUnits->findText(unit, Qt::MatchExactly));
187 *This function is used to init unit combobox. Start-tab view.
189 void CarMainWindow::initComboBoxStartTabUnits()
191 units << "km/h" << "km" << "h" << "m" << "min" << "Mile" << "Mph" << "in" << "ft" << "yrd";
192 ui->comboBoxStartTabUnits->addItems(units);
196 *This function is used to set items to unit combobox. Start-tab view.
197 *@param QStringlist units
199 void CarMainWindow::setComboBoxStartTabUnits(QStringList units)
201 ui->comboBoxStartTabUnits->addItems(units);
205 *This function is used to init listViewStartTabAccelerationCategories. Start-tab view.
207 void CarMainWindow::initListViewStartTabAccelerationCategories()
209 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";
210 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
211 ui->listViewStartTabAccelerationCategories->setModel(model);
215 *This function is used to set items to listViewStartTabAccelerationCategories. Start-tab view.
216 *@param QStringlist accelerationCategoriesStartTab
218 void CarMainWindow::setListViewStartTabAccelerationCategories(QStringList accelerationCategoriesStartTab)
220 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
221 ui->listViewStartTabAccelerationCategories->setModel(model);
225 *This function is used to set items to category combobox. Top-tab view.
228 void CarMainWindow::setCategoryCompoBox()
230 ui->comboBoxTopCategory->addItems(categorylist->getCategoryList());
234 *This function is used to set items to labelTopList. Top-tab view.
235 *@param QString category
237 void CarMainWindow::setListViewTopList(QString category, int size)
240 topList.append( categorylist->getTopList(category, size));
241 ui->labelTopList->setText(topList);
245 *This slot function is called when speed is achieved in measure dialog. Opens result dialog.
247 void CarMainWindow::openResultView()
253 *This slot function is called when registrate button is clicked.
255 void CarMainWindow::on_registratePushButton_clicked()
257 myRegistration->show();
261 *This slot function is called when ever refresh button clicked. Top-tab view.
263 void CarMainWindow::on_buttonTopRefresh_clicked()
265 myHttpClient->requestCategories();
266 setCategoryCompoBox();
270 *This slot function is called when ever category combobox current index changed. Top-tab view.
271 *@param QString category
272 *@todo Check where limitNr is taken.
274 void CarMainWindow::on_comboBoxTopCategory_currentIndexChanged(QString category)
276 int limitNr = 5; //replace with real value?
277 QString limit = QString::number(limitNr);
278 category = "acceleration-0-100"; //replace with real value from category list/top window
279 myHttpClient->requestTopList(category, limit);
280 setListViewTopList(category,10);
284 *This slot function is called when ever category combobox activated. Top-tab view.
285 *@param QString category
287 void CarMainWindow::on_comboBoxTopCategory_activated(QString category)
289 setListViewTopList(category,10);
293 *This slot function is called when set/change user button is clicked.
295 void CarMainWindow::on_setUserPushButton_clicked()
301 *@brief Just for development, for the real button is not shown until
302 *measurin started and there are results.
303 *@todo Implement with real code and yet leave sendXml in the bottom in use.
305 void CarMainWindow::on_manualStartButton_clicked()
311 * This slot function is called when timer gives timeout signal. Checks current speed
312 * and stores times in measure class.
314 void CarMainWindow::after_timeout()
316 QString timeString, speedString;
319 timeString.setNum(time);
320 speedString.setNum(speed);
321 ui->labelMeasureTabTime->setText(timeString);
322 ui->labelMeasureTabSpeed->setText(speedString);
324 //handleCheckPoint(time, speed);
328 * Initializes measures class's member variables.
330 void CarMainWindow::initializeMeasures()
332 measures->setTime10kmh(0);
333 measures->setTime20kmh(0);
334 measures->setTime30kmh(0);
335 measures->setTime40kmh(0);
336 measures->setTime50kmh(0);
337 measures->setTime60kmh(0);
338 measures->setTime70kmh(0);
339 measures->setTime80kmh(0);
340 measures->setTime90kmh(0);
341 measures->setTime100kmh(0);
345 * This slot function is called when Abort button is clicked.
347 void CarMainWindow::on_pushButtonMeasureTabAbort_clicked()
349 measures->setTime10kmh(0);
350 measures->setTime20kmh(0);
351 measures->setTime30kmh(0);
352 measures->setTime40kmh(0);
353 measures->setTime50kmh(0);
354 measures->setTime60kmh(0);
355 measures->setTime70kmh(0);
356 measures->setTime80kmh(0);
357 measures->setTime90kmh(0);
358 measures->setTime100kmh(0);
362 ui->tabWidget->setCurrentWidget(this->ui->StartTab);
366 void CarMainWindow::on_pushButtonSendResult_clicked()
368 myHttpClient->sendResultXml();
369 ui->pushButtonSendResult->setEnabled(false);
372 void CarMainWindow::updateUserName()
376 newUserName = myLogin->getUserName();
377 ui->userNameLabel->setText( "User: " + newUserName);
379 if (newUserName.length())
381 ui->setUserPushButton->setText( "Change User");
382 this->setWindowTitle("Speed freak - " + newUserName);
386 ui->setUserPushButton->setText( "Set User");
387 this->setWindowTitle("Speed freak");
391 void CarMainWindow::regUserToServer()
393 myHttpClient->requestRegistration();
397 void CarMainWindow::on_drawRoutePushButton_clicked()
403 * Opens result dialog when show result button is clicked.
404 * Sends measures as parameter to the resultdialogs saveMeasuresToArray-function.
406 void CarMainWindow::on_pushButtonShowResultDialog_clicked()
408 result->saveMeasuresToArray(measures);
409 this->result->show();
412 void CarMainWindow::userLogin()
414 myHttpClient->checkLogin();
418 * Resets Accelerometer measurement variables
420 void CarMainWindow::resetAccelerometerMeasurements()
422 currentAcceleration = 0;
423 currentAccelerationString = "";
426 distanceTraveled = "";
427 firstAcceleration = 0;
430 //lastScreenUpdateInSeconds = 0;
432 reverseAccelerationFlag = false;
433 stopWatch.setHMS(0, 0, 0, 0);
434 //accelerometer->stop();
436 vehicleStartedMoving = false;
441 * This function is called to handle checkpoints
442 *@param totalTime total time elapsed since starting measurements
443 *@param currentSpeed current speed of the device
445 void CarMainWindow::handleCheckPoint(double totalTime, double currentSpeed)
447 switch (counterForSaveResults)
450 measures->setTime10kmh(totalTime);
454 measures->setTime20kmh(totalTime);
458 measures->setTime30kmh(totalTime);
462 measures->setTime40kmh(totalTime);
466 measures->setTime50kmh(totalTime);
470 measures->setTime60kmh(totalTime);
474 measures->setTime70kmh(totalTime);
478 measures->setTime80kmh(totalTime);
482 measures->setTime90kmh(totalTime);
486 measures->setTime100kmh(totalTime);
492 counterForSaveResults++;
494 if (choiceInt == 0 && measures->getTime40kmh() != 0)
496 setTimeAxisGapAndShowResult(measures->getTime40kmh());
498 //this->accelerometerTimer->stop();
501 counterForSaveResults = 0;
504 else if (choiceInt == 1 && measures->getTime100kmh() != 0)
506 setTimeAxisGapAndShowResult(measures->getTime100kmh());
508 //this->accelerometerTimer->stop();
511 counterForSaveResults = 0;
515 else if (choiceInt != 1 && choiceInt != 0 && measures->getTime80kmh() != 0)
517 setTimeAxisGapAndShowResult(measures->getTime80kmh());
519 //this->accelerometerTimer->stop();
522 counterForSaveResults = 0;
532 *This function is called to read (and process) data from the accelerometer
534 void CarMainWindow::readAccelerometerData()
537 double changeInAcceleration = 0;
540 accelerometer->getAcceleration(x, y, z);
541 accelerometer->smoothData(x, y, z);
544 x -= accelerometer->getCalibrationX();
545 y -= accelerometer->getCalibrationY();
546 z -= accelerometer->getCalibrationZ();
548 QString str = QString("acc x: " + QString::number(x) + "\n" +
549 "acc y: " + QString::number(y) + "\n" +
550 "acc z: " + QString::number(z) + "\n");
552 if (!vehicleStartedMoving)
556 firstAcceleration = sqrt(x*x + y*y + z*z);
557 //firstAcceleration = y; // first read
562 currentAcceleration = sqrt(x*x + y*y + z*z);
563 changeInAcceleration = (currentAcceleration - firstAcceleration); // firstAcceleration only gets set once
565 if (((abs(changeInAcceleration) <= accelerationStartThreshold)
566 && !vehicleStartedMoving))
571 if (reverseAccelerationFlag)
573 // will be false until after 1st calculation
574 if ((changeInAcceleration <= 0))
576 // actually increasing here...
577 changeInAcceleration = abs(changeInAcceleration);
581 // actually decreasing here...
582 changeInAcceleration = (changeInAcceleration * -1);
585 if (!vehicleStartedMoving)
587 if ((changeInAcceleration < 0))
589 // we started to move backwards first time through
590 reverseAccelerationFlag = true;
591 changeInAcceleration = abs(changeInAcceleration);
593 vehicleStartedMoving = true;
595 stopWatch.setHMS(0, 0, 0, 0);
598 // keep the following line as close to the SetKinematicsProperties method as possible
599 currentTime = stopWatch.elapsed();
600 calculate->calculateParameters(changeInAcceleration, (currentTime - previousTime)/1000);
601 previousTime = currentTime;
603 s.sprintf("%.2f", changeInAcceleration);
604 currentAccelerationString = s;
607 speed = calculate->getCurrentSpeed();
608 speed = ((speed*1000)/kSecondsInHour);
609 s.sprintf("%.2f", speed);
612 s.sprintf("%.2f", calculate->getDistanceTraveled());
613 distanceTraveled = s;
619 time = calculate->getTotalTime();
621 s.sprintf("%.2f", time);
624 str.append("ca: " + currentAccelerationString + " G\n" );
625 str.append("cspeed: " + currentSpeed + " km/h \n" );
626 str.append("dist: " + distanceTraveled + " m \n" );
627 str.append("time: " + totalTime + " s \n" );
629 if ((stopTime > 0) && (previousTime >= stopTime))
631 // we want to end at a stopping point that the user chose
633 resetAccelerometerMeasurements();
638 *This function is used to calibrate accelerometer
640 void CarMainWindow::calibrateAccelerometer()
642 resetAccelerometerMeasurements();
643 accelerometer->calibrate();
647 *This slot function is called when GPS on checkbox state changed. Route-tab view.
650 void CarMainWindow::on_gpsOnCheckBox_stateChanged(int GPSState)
654 ui->labelRouteTabGPSStatus->setText("GPS off");//testing
655 location->stopPollingGPS();
659 ui->labelRouteTabGPSStatus->setText("GPS on");//testing
660 location->startPollingGPS();
665 *This slot function is called when GPS status changed. Route-tab view.
667 void CarMainWindow::gpsStatus()
669 if (ui->gpsOnCheckBox->isChecked())
671 if (location->getSatellitesInUse() >= 4)
674 ui->labelRouteTabGPSStatus->setText("GPS ready");
677 gpsTime->setTime_t(location->getTime());
678 ui->labelRouteTabGPSTime->setText(gpsTime->toString());
680 //Set latitude & longitude
681 ui->labelRouteTabLatitude->setText("Lat: " + QString::number(location->getLatitude()));
682 ui->labelRouteTabLongitude->setText("Lon: " + QString::number(location->getLongitude()));
687 ui->labelRouteTabGPSStatus->setText("Waiting for GPS");
693 *Sets time axis right way in result dialog and shows target speed result.
694 *@param double pTime is the target speed result time which is shown to the user.
696 void CarMainWindow::setTimeAxisGapAndShowResult(double pTime)
698 ui->pushButtonShowResultDialog->setEnabled(true);
700 timeInteger.setNum(pTime);
701 ui->labelMeasureTabResult->show();
702 ui->labelMeasureTabResult->setText(timeInteger);
704 if (floor(pTime) <= 5)
706 result->setDiagramGapHorizontal(80);
709 else if (floor(pTime) <= 10)
711 result->setDiagramGapHorizontal(40);
716 result->setDiagramGapHorizontal(20);