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 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 this->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 resetAccelerometerMeasurements();
149 ui->pushButtonSendResult->setEnabled(false);
150 ui->pushButtonShowResultDialog->setEnabled(false);
151 choice = ui->listViewStartTabAccelerationCategories->currentIndex();
152 choiceInt = choice.row();
153 qDebug() << choiceInt;
156 ui->labelMeasureTabHeader->setText("Accelerate to 40 km/h");
157 result->setDiagramGapStem(75);
160 else if (choiceInt == 1)
162 ui->labelMeasureTabHeader->setText("Accelerate to 100 km/h");
163 result->setDiagramGapStem(30);
168 ui->labelMeasureTabHeader->setText("Accelerate to 80 km/h");
169 result->setDiagramGapStem(37.5);
171 ui->labelMeasureTabResult->setText("");
173 this->accelerometerTimer->start(kAccelerometerSampleRate);
174 this->timer->start();
177 ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
181 *This slot function is called when ever list view is update. Start-tab view.
182 *@param QString unit.
184 void CarMainWindow::updateComboBoxStartTabUnits(QString unit)
186 ui->comboBoxStartTabUnits->setCurrentIndex(ui->comboBoxStartTabUnits->findText(unit, Qt::MatchExactly));
190 *This function is used to init unit combobox. Start-tab view.
192 void CarMainWindow::initComboBoxStartTabUnits()
194 units << "km/h" << "km" << "h" << "m" << "min" << "Mile" << "Mph" << "in" << "ft" << "yrd";
195 ui->comboBoxStartTabUnits->addItems(units);
199 *This function is used to set items to unit combobox. Start-tab view.
200 *@param QStringlist units
202 void CarMainWindow::setComboBoxStartTabUnits(QStringList units)
204 ui->comboBoxStartTabUnits->addItems(units);
208 *This function is used to init listViewStartTabAccelerationCategories. Start-tab view.
210 void CarMainWindow::initListViewStartTabAccelerationCategories()
212 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";
213 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
214 ui->listViewStartTabAccelerationCategories->setModel(model);
218 *This function is used to set items to listViewStartTabAccelerationCategories. Start-tab view.
219 *@param QStringlist accelerationCategoriesStartTab
221 void CarMainWindow::setListViewStartTabAccelerationCategories(QStringList accelerationCategoriesStartTab)
223 QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
224 ui->listViewStartTabAccelerationCategories->setModel(model);
228 *This function is used to set items to category combobox. Top-tab view.
231 void CarMainWindow::setCategoryCompoBox()
233 ui->comboBoxTopCategory->addItems(categorylist->getCategoryList());
237 *This function is used to set items to labelTopList. Top-tab view.
238 *@param QString category
240 void CarMainWindow::setListViewTopList(QString category, int size)
243 topList.append( categorylist->getTopList(category, size));
244 ui->labelTopList->setText(topList);
248 *This slot function is called when speed is achieved in measure dialog. Opens result dialog.
250 void CarMainWindow::openResultView()
256 *This slot function is called when registrate button is clicked.
258 void CarMainWindow::on_registratePushButton_clicked()
260 myRegistration->show();
264 *This slot function is called when ever refresh button clicked. Top-tab view.
266 void CarMainWindow::on_buttonTopRefresh_clicked()
268 myHttpClient->requestCategories();
269 setCategoryCompoBox();
273 *This slot function is called when ever category combobox current index changed. Top-tab view.
274 *@param QString category
275 *@todo Check where limitNr is taken.
277 void CarMainWindow::on_comboBoxTopCategory_currentIndexChanged(QString category)
279 int limitNr = 5; //replace with real value?
280 QString limit = QString::number(limitNr);
281 category = "acceleration-0-100"; //replace with real value from category list/top window
282 myHttpClient->requestTopList(category, limit);
283 setListViewTopList(category,10);
287 *This slot function is called when ever category combobox activated. Top-tab view.
288 *@param QString category
290 void CarMainWindow::on_comboBoxTopCategory_activated(QString category)
292 setListViewTopList(category,10);
296 *This slot function is called when set/change user button is clicked.
298 void CarMainWindow::on_setUserPushButton_clicked()
304 *@brief Just for development, for the real button is not shown until
305 *measurin started and there are results.
306 *@todo Implement with real code and yet leave sendXml in the bottom in use.
308 void CarMainWindow::on_manualStartButton_clicked()
314 * This slot function is called when timer gives timeout signal. Checks current speed
315 * and stores times in measure class.
317 void CarMainWindow::after_timeout()
319 QString timeString, speedString;
322 timeString.setNum(time);
323 speedString.setNum(speed);
324 ui->labelMeasureTabTime->setText(timeString);
325 ui->labelMeasureTabSpeed->setText(speedString);
327 //handleCheckPoint(time, speed);
331 * Initializes measures class's member variables.
333 void CarMainWindow::initializeMeasures()
335 measures->setTime10kmh(0);
336 measures->setTime20kmh(0);
337 measures->setTime30kmh(0);
338 measures->setTime40kmh(0);
339 measures->setTime50kmh(0);
340 measures->setTime60kmh(0);
341 measures->setTime70kmh(0);
342 measures->setTime80kmh(0);
343 measures->setTime90kmh(0);
344 measures->setTime100kmh(0);
348 * This slot function is called when Abort button is clicked.
350 void CarMainWindow::on_pushButtonMeasureTabAbort_clicked()
352 ui->pushButtonSendResult->setEnabled(false);
353 ui->pushButtonShowResultDialog->setEnabled(false);
354 ui->labelMeasureTabResult->hide();
355 ui->labelMeasureTabTime->setText("");
356 ui->labelMeasureTabSpeed->setText("");
357 measures->setTime10kmh(0);
358 measures->setTime20kmh(0);
359 measures->setTime30kmh(0);
360 measures->setTime40kmh(0);
361 measures->setTime50kmh(0);
362 measures->setTime60kmh(0);
363 measures->setTime70kmh(0);
364 measures->setTime80kmh(0);
365 measures->setTime90kmh(0);
366 measures->setTime100kmh(0);
367 this->accelerometerTimer->stop();
371 ui->tabWidget->setCurrentWidget(this->ui->StartTab);
375 void CarMainWindow::on_pushButtonSendResult_clicked()
377 myHttpClient->sendResultXml();
378 ui->pushButtonSendResult->setEnabled(false);
381 void CarMainWindow::updateUserName()
385 newUserName = myLogin->getUserName();
386 ui->userNameLabel->setText( "User: " + newUserName);
388 if (newUserName.length())
390 ui->setUserPushButton->setText( "Change User");
391 this->setWindowTitle("Speed freak - " + newUserName);
395 ui->setUserPushButton->setText( "Set User");
396 this->setWindowTitle("Speed freak");
400 void CarMainWindow::regUserToServer()
402 myHttpClient->requestRegistration();
406 void CarMainWindow::on_drawRoutePushButton_clicked()
412 * Opens result dialog when show result button is clicked.
413 * Sends measures as parameter to the resultdialogs saveMeasuresToArray-function.
415 void CarMainWindow::on_pushButtonShowResultDialog_clicked()
417 result->saveMeasuresToArray(measures);
418 this->result->show();
421 void CarMainWindow::userLogin()
423 myHttpClient->checkLogin();
427 * Resets Accelerometer measurement variables
429 void CarMainWindow::resetAccelerometerMeasurements()
431 currentAcceleration = 0;
432 currentAccelerationString = "";
435 distanceTraveled = "";
436 firstAcceleration = 0;
439 //lastScreenUpdateInSeconds = 0;
441 reverseAccelerationFlag = false;
442 stopWatch.setHMS(0, 0, 0, 0);
443 //accelerometer->stop();
445 vehicleStartedMoving = false;
450 * This function is called to handle checkpoints
451 *@param totalTime total time elapsed since starting measurements
452 *@param currentSpeed current speed of the device
454 void CarMainWindow::handleCheckPoint(double totalTime, double currentSpeed)
456 switch (counterForSaveResults)
459 measures->setTime10kmh(totalTime);
463 measures->setTime20kmh(totalTime);
467 measures->setTime30kmh(totalTime);
471 measures->setTime40kmh(totalTime);
475 measures->setTime50kmh(totalTime);
479 measures->setTime60kmh(totalTime);
483 measures->setTime70kmh(totalTime);
487 measures->setTime80kmh(totalTime);
491 measures->setTime90kmh(totalTime);
495 measures->setTime100kmh(totalTime);
501 counterForSaveResults++;
503 if (choiceInt == 0 && measures->getTime40kmh() != 0)
505 setTimeAxisGapAndShowResult(measures->getTime40kmh());
507 this->accelerometerTimer->stop();
510 counterForSaveResults = 0;
513 else if (choiceInt == 1 && measures->getTime100kmh() != 0)
515 setTimeAxisGapAndShowResult(measures->getTime100kmh());
517 this->accelerometerTimer->stop();
520 counterForSaveResults = 0;
524 else if (choiceInt != 1 && choiceInt != 0 && measures->getTime80kmh() != 0)
526 setTimeAxisGapAndShowResult(measures->getTime80kmh());
528 this->accelerometerTimer->stop();
531 counterForSaveResults = 0;
541 *This function is called to read (and process) data from the accelerometer
543 void CarMainWindow::readAccelerometerData()
546 double changeInAcceleration = 0;
549 accelerometer->getAcceleration(x, y, z);
550 accelerometer->smoothData(x, y, z);
553 x -= accelerometer->getCalibrationX();
554 y -= accelerometer->getCalibrationY();
555 z -= accelerometer->getCalibrationZ();
557 QString str = QString("acc x: " + QString::number(x) + "\n" +
558 "acc y: " + QString::number(y) + "\n" +
559 "acc z: " + QString::number(z) + "\n");
561 if (!vehicleStartedMoving)
565 firstAcceleration = sqrt(x*x + y*y + z*z);
566 //firstAcceleration = y; // first read
571 currentAcceleration = sqrt(x*x + y*y + z*z);
572 changeInAcceleration = (currentAcceleration - firstAcceleration); // firstAcceleration only gets set once
574 if (((fabs(changeInAcceleration) <= accelerationStartThreshold)
575 && !vehicleStartedMoving))
580 if (reverseAccelerationFlag)
582 // will be false until after 1st calculation
583 if ((changeInAcceleration <= 0))
585 // actually increasing here...
586 changeInAcceleration = fabs(changeInAcceleration);
590 // actually decreasing here...
591 changeInAcceleration = (changeInAcceleration * -1);
594 if (!vehicleStartedMoving)
596 if ((changeInAcceleration < 0))
598 // we started to move backwards first time through
599 reverseAccelerationFlag = true;
600 changeInAcceleration = fabs(changeInAcceleration);
602 vehicleStartedMoving = true;
604 stopWatch.setHMS(0, 0, 0, 0);
607 // keep the following line as close to the SetKinematicsProperties method as possible
608 currentTime = stopWatch.elapsed();
609 calculate->calculateParameters(changeInAcceleration, (currentTime - previousTime)/1000);
610 previousTime = currentTime;
612 s.sprintf("%.2f", changeInAcceleration);
613 currentAccelerationString = s;
616 speed = calculate->getCurrentSpeed();
617 speed = ((speed*1000)/kSecondsInHour);
618 s.sprintf("%.2f", speed);
621 s.sprintf("%.2f", calculate->getDistanceTraveled());
622 distanceTraveled = s;
628 time = calculate->getTotalTime();
630 s.sprintf("%.2f", time);
633 str.append("ca: " + currentAccelerationString + " G\n" );
634 str.append("cspeed: " + currentSpeed + " km/h \n" );
635 str.append("dist: " + distanceTraveled + " m \n" );
636 str.append("time: " + totalTime + " s \n" );
638 if ((stopTime > 0) && (previousTime >= stopTime))
640 // we want to end at a stopping point that the user chose
642 resetAccelerometerMeasurements();
647 *This function is used to calibrate accelerometer
649 void CarMainWindow::calibrateAccelerometer()
651 resetAccelerometerMeasurements();
652 accelerometer->calibrate();
656 *This slot function is called when GPS on checkbox state changed. Route-tab view.
659 void CarMainWindow::on_gpsOnCheckBox_stateChanged(int GPSState)
663 ui->labelRouteTabGPSStatus->setText("GPS off");//testing
664 location->stopPollingGPS();
668 ui->labelRouteTabGPSStatus->setText("GPS on");//testing
669 location->startPollingGPS();
674 *This slot function is called when GPS status changed. Route-tab view.
676 void CarMainWindow::gpsStatus()
678 if (ui->gpsOnCheckBox->isChecked())
680 if (location->getSatellitesInUse() >= 4)
683 ui->labelRouteTabGPSStatus->setText("GPS ready");
686 gpsTime->setTime_t(location->getTime());
687 ui->labelRouteTabGPSTime->setText(gpsTime->toString());
689 //Set latitude & longitude
690 ui->labelRouteTabLatitude->setText("Lat: " + QString::number(location->getLatitude()));
691 ui->labelRouteTabLongitude->setText("Lon: " + QString::number(location->getLongitude()));
696 ui->labelRouteTabGPSStatus->setText("Waiting for GPS");
702 *Sets time axis right way in result dialog and shows target speed result.
703 *@param double pTime is the target speed result time which is shown to the user.
705 void CarMainWindow::setTimeAxisGapAndShowResult(double pTime)
707 ui->pushButtonShowResultDialog->setEnabled(true);
708 ui->pushButtonSendResult->setEnabled(true);
710 timeInteger.setNum(pTime);
711 ui->labelMeasureTabResult->show();
712 ui->labelMeasureTabResult->setText(timeInteger);
714 if (floor(pTime) <= 5)
716 result->setDiagramGapHorizontal(80);
719 else if (floor(pTime) <= 10)
721 result->setDiagramGapHorizontal(40);
726 result->setDiagramGapHorizontal(20);