examples/sensors/test_manual/test_manual.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 #include <QObject>
       
    42 #include <QTest>
       
    43 #include <QDebug>
       
    44 #include <QSettings>
       
    45 #include <iostream>
       
    46 
       
    47 
       
    48 #include <qsensor.h>
       
    49 #include <qorientationsensor.h>
       
    50 #include <qaccelerometer.h>
       
    51 #include <qrotationsensor.h>
       
    52 #include <qmagnetometer.h>
       
    53 #include <qcompass.h>
       
    54 #include "sensorslotclass.h"
       
    55 
       
    56 QTM_USE_NAMESPACE
       
    57 
       
    58         static QOrientationReading::Orientation o2;
       
    59 static QOrientationSensor orientationSensor;
       
    60 static QAccelerometer accelerometer;
       
    61 static QRotationSensor rotationSensor;
       
    62 static QAccelerometerReading* acceReading;
       
    63 static QRotationReading* rotReading;
       
    64 static QMagnetometer magnetometer;
       
    65 static QMagnetometerReading* maggeReading;
       
    66 static QCompass compass;
       
    67 static QCompassReading* compassReading;
       
    68 
       
    69 
       
    70 static QString dataRateString;
       
    71 static QString dataRangeString;
       
    72 static QString resolutionString;
       
    73 static int counter;
       
    74 static bool isStationary = false;
       
    75 
       
    76 ///////////////////////////////////////////
       
    77 //cpp file
       
    78 ///////////////////////////////////////////
       
    79 
       
    80 
       
    81 SensorSlotClass::SensorSlotClass()
       
    82 {
       
    83     int rateMax =0;
       
    84     connect(&orientationSensor, SIGNAL(readingChanged()), this, SLOT(slotOrientationData()));
       
    85     if (orientationSensor.availableDataRates().size()>0){
       
    86         rateMax = orientationSensor.availableDataRates().at(0).second;
       
    87         orientationSensor.setDataRate(rateMax);
       
    88     }
       
    89     orientationSensor.start();
       
    90     connect(&accelerometer, SIGNAL(readingChanged()), this, SLOT(slotAccelerationData()));
       
    91     if (accelerometer.availableDataRates().size()>0){
       
    92         rateMax = accelerometer.availableDataRates().at(0).second;
       
    93         accelerometer.setDataRate(rateMax);
       
    94     }
       
    95     accelerometer.start();
       
    96     connect(&rotationSensor, SIGNAL(readingChanged()), this, SLOT(slotRotationData()));
       
    97     if (rotationSensor.availableDataRates().size()>0){
       
    98         rateMax = rotationSensor.availableDataRates().at(0).second;
       
    99         rotationSensor.setDataRate(rateMax);
       
   100     }
       
   101     rotationSensor.start();
       
   102     magnetometer.setProperty("returnGeoValues", true);
       
   103     connect(&magnetometer, SIGNAL(readingChanged()), this, SLOT(slotMagnetometerData()));
       
   104     if (magnetometer.availableDataRates().size()>0){
       
   105         rateMax = magnetometer.availableDataRates().at(0).second;
       
   106         magnetometer.setDataRate(rateMax);
       
   107     }
       
   108     magnetometer.start();
       
   109 
       
   110     connect(&compass, SIGNAL(readingChanged()), this, SLOT(slotCompassData()));
       
   111     if (compass.availableDataRates().size()>0){
       
   112         rateMax = compass.availableDataRates().at(0).second;
       
   113         compass.setDataRate(rateMax);
       
   114     }
       
   115     compass.start();
       
   116 
       
   117     m_x=0; m_y=0; m_z=0;
       
   118 }
       
   119 
       
   120 SensorSlotClass::~SensorSlotClass(){
       
   121     disconnect(&compass);
       
   122     compass.stop();
       
   123 
       
   124     disconnect(&orientationSensor);
       
   125     orientationSensor.stop();
       
   126 
       
   127     disconnect(&rotationSensor);
       
   128     rotationSensor.stop();
       
   129 
       
   130     disconnect(&magnetometer);
       
   131     magnetometer.stop();
       
   132 
       
   133     disconnect(&accelerometer);
       
   134     accelerometer.stop();
       
   135 
       
   136 }
       
   137 
       
   138 
       
   139 void SensorSlotClass::slotOrientationData(){
       
   140     o2 = orientationSensor.reading()->orientation();
       
   141     checkRange(&orientationSensor, o2);
       
   142     checkRate(&orientationSensor, m_orientationTimestamp);
       
   143 }
       
   144 
       
   145 
       
   146 void SensorSlotClass::slotAccelerationData(){
       
   147 
       
   148     acceReading = accelerometer.reading();
       
   149     checkRange(&accelerometer, acceReading->x());
       
   150     checkRange(&accelerometer, acceReading->y());
       
   151     checkRange(&accelerometer, acceReading->z());
       
   152 
       
   153     checkRate(&accelerometer, m_accelerometerTimestamp);
       
   154 
       
   155     if (isStationary) checkResolution(&accelerometer, acceReading);
       
   156 
       
   157 }
       
   158 
       
   159 void SensorSlotClass::slotRotationData(){
       
   160     rotReading = rotationSensor.reading();
       
   161     checkRange(&rotationSensor, rotReading->x());
       
   162     checkRange(&rotationSensor, rotReading->y());
       
   163     checkRange(&rotationSensor, rotReading->z());
       
   164 
       
   165     checkRate(&rotationSensor, m_rotationTimestamp);
       
   166 }
       
   167 
       
   168 void SensorSlotClass::slotMagnetometerData(){
       
   169 
       
   170     maggeReading = magnetometer.reading();
       
   171     checkRange(&magnetometer, maggeReading->x());
       
   172     checkRange(&magnetometer, maggeReading->y());
       
   173     checkRange(&magnetometer, maggeReading->z());
       
   174 
       
   175     checkRate(&magnetometer, m_magnetometerTimestamp);
       
   176 
       
   177 }
       
   178 
       
   179 void SensorSlotClass::slotCompassData(){
       
   180     compassReading = compass.reading();
       
   181     checkRange(&compass, (qreal)compassReading->azimuth());
       
   182 
       
   183     checkRate(&compass, m_compassTimestamp);
       
   184 }
       
   185 
       
   186 
       
   187 void SensorSlotClass::checkRange(QSensor* sensor, qreal value){
       
   188     qreal min = sensor->outputRanges().at(sensor->outputRange()).minimum;
       
   189     qreal max = sensor->outputRanges().at(sensor->outputRange()).maximum;
       
   190 
       
   191     if (min>value || value> max){
       
   192         QString num;
       
   193         dataRangeString.append(sensor->type());
       
   194         dataRangeString.append(": range=[");
       
   195         dataRangeString.append(num.setNum(min));
       
   196         dataRangeString.append(",");
       
   197         dataRangeString.append(num.setNum(max));
       
   198         dataRangeString.append("], value =");
       
   199         dataRangeString.append(num.setNum(value));
       
   200         dataRangeString.append("\n");
       
   201     }
       
   202 
       
   203 }
       
   204 
       
   205 
       
   206 void SensorSlotClass::checkRate(QSensor* sensor, int &exTimestamp){
       
   207     int timestamp = sensor->reading()->timestamp();
       
   208     int diff = timestamp - exTimestamp;
       
   209     int rate = sensor->dataRate();
       
   210     if (rate==0) return;
       
   211     if (diff < (1000/rate)*0.9){
       
   212         dataRateString.append(sensor->type());
       
   213         dataRateString.append(": rate=");
       
   214         dataRateString.append(sensor->dataRate());
       
   215         dataRateString.append(", measured rate=");
       
   216         dataRateString.append(1000/diff);
       
   217         dataRateString.append("\n");
       
   218     }
       
   219 
       
   220     exTimestamp = timestamp;
       
   221 }
       
   222 
       
   223 
       
   224 void SensorSlotClass::checkResolution(QSensor* sensor, QAccelerometerReading* reading){
       
   225     qreal x = reading->x();
       
   226     qreal y = reading->y();
       
   227     qreal z = reading->z();
       
   228 
       
   229 
       
   230     qreal resolution = sensor->outputRanges().at(sensor->outputRange()).accuracy;
       
   231 
       
   232     if (m_x!=0){
       
   233         qreal diff = qAbs(x-m_x);
       
   234         checkDiff(diff, resolution, ": x resolution=");
       
   235         diff = qAbs(y-m_y);
       
   236         checkDiff(diff, resolution, ": y resolution=");
       
   237         diff = qAbs(z-m_z);
       
   238         checkDiff(diff, resolution, ": z resolution=");
       
   239     }
       
   240     m_x = x;
       
   241     m_y = y;
       
   242     m_z = z;
       
   243 
       
   244 }
       
   245 
       
   246 void SensorSlotClass::checkDiff(qreal diff, qreal resolution, QString msg){
       
   247     if (diff==0) return;
       
   248     qreal resolutionMax = 3*resolution;
       
   249 
       
   250 
       
   251     if (qAbs(diff)<resolution || qAbs(diff)>resolutionMax){
       
   252         QString num;
       
   253         resolutionString.append("\n");
       
   254         resolutionString.append("accelerometer:");
       
   255         resolutionString.append(msg);
       
   256         num.setNum(resolution);
       
   257         resolutionString.append(num);
       
   258         resolutionString.append("!=");
       
   259         num.setNum(qAbs(diff));
       
   260         resolutionString.append(num);
       
   261     }
       
   262 
       
   263 }
       
   264 
       
   265 
       
   266 
       
   267 namespace tests{
       
   268 
       
   269     static QOrientationReading::Orientation orientation[] = {
       
   270         QOrientationReading::TopUp,
       
   271         QOrientationReading::TopDown,
       
   272         QOrientationReading::LeftUp,
       
   273         QOrientationReading::RightUp,
       
   274         QOrientationReading::FaceUp,
       
   275         QOrientationReading::FaceDown
       
   276     };
       
   277 
       
   278 
       
   279     static const float GRAVITY_EARTH = 9.80665;
       
   280     static const float THRESHOLD = GRAVITY_EARTH/4;
       
   281 
       
   282     static void pressAnyKey()
       
   283     {
       
   284         std::string value;
       
   285         qDebug()<< "Press any key: \n";
       
   286         std::getline(std::cin, value);
       
   287     }
       
   288 
       
   289 
       
   290     static QString debugMessage(QString title, qreal expected, qreal measured, qreal threshold){
       
   291         QString msg;
       
   292         msg.append(title);
       
   293         QString num;
       
   294         num.setNum(measured);
       
   295         msg.append(num);
       
   296         msg.append(" was not in range [");
       
   297         num.setNum(expected - threshold);
       
   298         msg.append(num);
       
   299         msg.append(",");
       
   300         num.setNum(expected + threshold);
       
   301         msg.append(num);
       
   302         msg.append("]");
       
   303         msg.append("\n");
       
   304         return msg;
       
   305     }
       
   306 
       
   307 
       
   308     static void drawDevice(QOrientationReading::Orientation orientation){
       
   309         switch (orientation) {
       
   310         case QOrientationReading::TopUp:
       
   311             std::cout<<"    ___________\n";
       
   312             std::cout<<"    | _______ |\n";
       
   313             std::cout<<"    | |     | |\n";
       
   314             std::cout<<"    | |     | |\n";
       
   315             std::cout<<"    | |_____| |\n";
       
   316             std::cout<<"    | _______ |\n";
       
   317             std::cout<<"    | |_|_|_| |\n";
       
   318             std::cout<<"    | |_|_|_| |\n";
       
   319             std::cout<<"    | |_|_|_| |\n";
       
   320             std::cout<<"    |_________|\n";
       
   321             std::cout<< "Top up \n"; break;
       
   322             break;
       
   323         case QOrientationReading::TopDown:
       
   324             std::cout<<"     _________ \n";
       
   325             std::cout<<"    | _______ |\n";
       
   326             std::cout<<"    | |_|_|_| |\n";
       
   327             std::cout<<"    | |_|_|_| |\n";
       
   328             std::cout<<"    | |_|_|_| |\n";
       
   329             std::cout<<"    | _______ |\n";
       
   330             std::cout<<"    | |     | |\n";
       
   331             std::cout<<"    | |     | |\n";
       
   332             std::cout<<"    | |_____| |\n";
       
   333             std::cout<<"    |_________|\n";
       
   334             std::cout<<"Top down \n"; break;
       
   335         case QOrientationReading::LeftUp:
       
   336             std::cout<<"     _________________\n";
       
   337             std::cout<<"    | _______ ______  |\n";
       
   338             std::cout<<"    | |_|_|_| |     | |\n";
       
   339             std::cout<<"    | |_|_|_| |     | |\n";
       
   340             std::cout<<"    | |_|_|_| |_____| |\n";
       
   341             std::cout<<"    |_________________|\n";
       
   342             std::cout<<"Left up  \n"; break;
       
   343         case QOrientationReading::RightUp:
       
   344             std::cout<<"     _________________\n";
       
   345             std::cout<<"    | _______ ______  |\n";
       
   346             std::cout<<"    | |     | |_|_|_| |\n";
       
   347             std::cout<<"    | |     | |_|_|_| |\n";
       
   348             std::cout<<"    | |_____| |_|_|_| |\n";
       
   349             std::cout<<"    |_________________|\n";
       
   350             std::cout<<"Right up \n"; break;
       
   351         case QOrientationReading::FaceUp:
       
   352             std::cout<<"     _________\n";
       
   353             std::cout<<"    |  ' ' '  |\n";
       
   354             std::cout<<"    |_________|\n";
       
   355             std::cout<<"Face up  \n"; break;
       
   356         case QOrientationReading::FaceDown:
       
   357             std::cout<<"     _________\n";
       
   358             std::cout<<"    |         |\n";
       
   359             std::cout<<"    |__._._.__|\n";
       
   360             std::cout<<"Face down\n"; break;
       
   361         case QOrientationReading::Undefined: std::cout<<"Undefined\n"; break;
       
   362         default: std::cout<<"Invalid enum value\n";
       
   363         }
       
   364     }
       
   365 
       
   366 
       
   367     static const char* orientationAsString(QOrientationReading::Orientation orientation){
       
   368         switch (orientation) {
       
   369         case QOrientationReading::TopUp:     return "Top up   ";
       
   370         case QOrientationReading::TopDown:   return "Top down ";
       
   371         case QOrientationReading::LeftUp:    return  "Left up  ";
       
   372         case QOrientationReading::RightUp:   return "Right up ";
       
   373         case QOrientationReading::FaceUp:    return "Face up  ";
       
   374         case QOrientationReading::FaceDown:  return "Face down";
       
   375         case QOrientationReading::Undefined: return "Undefined";
       
   376         default: return "Invalid enum value";
       
   377         }
       
   378     }
       
   379 
       
   380 
       
   381     static qreal acce_array[6][3]=
       
   382     {
       
   383         {0, tests::GRAVITY_EARTH, 0},
       
   384         {0, -tests::GRAVITY_EARTH, 0},
       
   385         {-tests::GRAVITY_EARTH, 0, 0},
       
   386         {tests::GRAVITY_EARTH, 0, 0},
       
   387         {0, 0, tests::GRAVITY_EARTH},
       
   388         {0, 0, -tests::GRAVITY_EARTH}};
       
   389 
       
   390 
       
   391     static qreal rot_array[6][2]=
       
   392     {
       
   393         {90,0},
       
   394         {-90, 0},
       
   395         {0,90},
       
   396         {0,-90},
       
   397         {0, 0},
       
   398         {0, 180}};
       
   399 
       
   400     static const qreal ROT_THRESHOLD = 20;
       
   401 
       
   402 
       
   403     static bool confirm()
       
   404     {
       
   405         std::string value;
       
   406         while (true){
       
   407             qDebug()<< "Answer(y/N):";
       
   408             std::getline(std::cin, value);
       
   409             if (value.compare("Y")==0 || value.compare("y")==0 ) return true;
       
   410             if (value.compare("N")==0 || value.compare("n")==0 || value.compare("")==0 || value.compare(" ")==0 || value.compare("\n")==0) return false;
       
   411         }
       
   412     }
       
   413 
       
   414     static bool testMagge(qreal val1, qreal val2, qreal threshold, QString &msg){
       
   415         bool isOk = true;
       
   416 
       
   417         if (val1+val2>threshold){
       
   418             isOk = false;
       
   419             QString num;
       
   420             msg.append(num.setNum(val1));
       
   421             msg.append("!=");
       
   422             msg.append(num.setNum(val2));
       
   423             msg.append("\n");
       
   424         }
       
   425         return isOk;
       
   426     }
       
   427 
       
   428 
       
   429 
       
   430     static bool testMagge2(qreal valBig, qreal valSmall1, qreal valSmall2, QString &msg){
       
   431         bool isOk = true;
       
   432         if (qAbs(valBig)< qAbs(valSmall1) || qAbs(valBig)< qAbs(valSmall2)){
       
   433             isOk = false;
       
   434             QString num;
       
   435             msg.append(num.setNum(valBig));
       
   436             msg.append(",");
       
   437             msg.append(num.setNum(valSmall1));
       
   438             msg.append(",");
       
   439             msg.append(num.setNum(valSmall2));
       
   440             msg.append("\n");
       
   441         }
       
   442         return isOk;
       
   443     }
       
   444 
       
   445 
       
   446     static bool testCompass(qreal val1, qreal val2, QString &msg){
       
   447         bool isOk = true;
       
   448         int threshold = 30;
       
   449 
       
   450 
       
   451         if (qAbs(val1 - val2)> threshold){
       
   452             if (val1>360-threshold)
       
   453                 if ((360 - val1 + val2)< threshold) return isOk;
       
   454             if (val2>360-threshold)
       
   455                 if ((360 - val2 + val1)< threshold) return isOk;
       
   456             isOk = false;
       
   457             msg.append("Compass failure:");
       
   458             QString num;
       
   459             msg.append(num.setNum(val1));
       
   460             msg.append("!=");
       
   461             msg.append(num.setNum(val2));
       
   462             msg.append("\n");
       
   463         }
       
   464         return isOk;
       
   465     }
       
   466 
       
   467 
       
   468     static bool testRot(qreal azimuth, qreal rotZ, QString &msg){
       
   469         bool isOk = true;
       
   470 
       
   471 
       
   472         qreal tmpAzimuth = rotZ>0 ? 360 -rotZ : -rotZ;
       
   473         int threshold = 30;
       
   474 
       
   475 
       
   476         if (qAbs(azimuth - tmpAzimuth)> threshold){
       
   477             if (tmpAzimuth> 360-threshold)
       
   478                 if ((360 - tmpAzimuth + azimuth)< threshold) return isOk;
       
   479             if (azimuth> 360-threshold)
       
   480                 if ((360 - azimuth + tmpAzimuth)< threshold) return isOk;
       
   481 
       
   482             isOk=false;
       
   483             msg.append("Rot/compass comparison failed: ");
       
   484             QString num;
       
   485             msg.append(num.setNum(azimuth));
       
   486             msg.append("!=");
       
   487             msg.append(num.setNum(tmpAzimuth));
       
   488             msg.append("\n");
       
   489         }
       
   490 
       
   491         return isOk;
       
   492     }
       
   493 
       
   494 
       
   495 
       
   496 }
       
   497 
       
   498 
       
   499 class test_manual: public QObject{
       
   500     Q_OBJECT
       
   501     private slots:
       
   502     void testOrientation();
       
   503     void testDataRate();
       
   504     void testOutputRange();
       
   505     void testResolution();
       
   506 };
       
   507 
       
   508 
       
   509 void test_manual::testOrientation()
       
   510 
       
   511 {
       
   512 
       
   513     SensorSlotClass slotClass;
       
   514 
       
   515     bool hasZ = rotationSensor.property("hasZ").toBool();
       
   516 
       
   517     int j=0,k=0,l=0;
       
   518 
       
   519 
       
   520     qreal magge_x[6];
       
   521     qreal magge_y[6];
       
   522     qreal magge_z[6];
       
   523     qreal rot_x[6];
       
   524     qreal rot_y[6];
       
   525     qreal rot_z[6];
       
   526     qreal compass_azimuth[6];
       
   527     qreal compass_level[6];
       
   528 
       
   529     QString tmp("\n");
       
   530 
       
   531 
       
   532     for (; counter<7; counter++){
       
   533         qDebug()<<"Put the device in following position, try to preserve compass direction:\n";
       
   534         if (counter==4) qDebug()<<"Put the device on the table on stationary position!:\n";
       
   535         QOrientationReading::Orientation o1 = tests::orientation[counter%6];
       
   536         tests::drawDevice(o1);
       
   537         tests::pressAnyKey();
       
   538         QTest::qWait(50);   // DO NOT REMOVE - does not work without this!
       
   539 
       
   540         if (counter==0) continue;     //prevent from first UNDEFINED VALUE
       
   541 
       
   542 
       
   543         if (o1!=o2){
       
   544             j++;
       
   545             tmp.append("Orientation: expected/measured: \n");
       
   546             tmp.append(tests::orientationAsString(o1));
       
   547             tmp.append("!=");
       
   548             tmp.append(tests::orientationAsString(o2));
       
   549             tmp.append("\n");
       
   550         }
       
   551 
       
   552 
       
   553         //acceleration
       
   554         qreal tmpX = tests::acce_array[counter%6][0];
       
   555         qreal tmpY = tests::acce_array[counter%6][1];
       
   556         qreal tmpZ = tests::acce_array[counter%6][2];
       
   557         qreal x = acceReading->x();
       
   558         qreal y = acceReading->y();
       
   559         qreal z = acceReading->z();
       
   560 
       
   561         QString accTmp;
       
   562         int tmpK = k;
       
   563         if (qAbs(x-tmpX)>tests::THRESHOLD){
       
   564             k++;
       
   565             accTmp.append(tests::debugMessage("Acceleration X: ",tmpX, x, tests::THRESHOLD));
       
   566         }
       
   567 
       
   568         if (qAbs(y-tmpY)>tests::THRESHOLD){
       
   569             k++;
       
   570             accTmp.append(tests::debugMessage("Acceleration Y: ",tmpY, y, tests::THRESHOLD));
       
   571         }
       
   572 
       
   573         if (qAbs(z-tmpZ)>tests::THRESHOLD){
       
   574             k++;
       
   575             accTmp.append(tests::debugMessage("Acceleration Z: ",tmpZ, z, tests::THRESHOLD));
       
   576         }
       
   577         if (k>tmpK){
       
   578             tmp.append("Acceleration failure when in ");
       
   579             tmp.append(tests::orientationAsString(o2));
       
   580             tmp.append("\n");
       
   581             tmp.append(accTmp);
       
   582         }
       
   583 
       
   584         //rotation
       
   585         QString rotTmp;
       
   586         tmpX = tests::rot_array[counter%6][0];
       
   587         tmpY = tests::rot_array[counter%6][1];
       
   588         x = rotReading->x();
       
   589         y = rotReading->y();
       
   590         if (hasZ){
       
   591             rot_x[counter-1]=rotReading->x();
       
   592             rot_y[counter-1]=rotReading->y();
       
   593             rot_z[counter-1]=rotReading->z();
       
   594         }
       
   595         int tmpL = l;
       
   596         // not as straight-forward
       
   597         if (qAbs(x-tmpX)>tests::ROT_THRESHOLD){
       
   598             l++;
       
   599             rotTmp.append(tests::debugMessage("Rotation X: ", tmpX, x, tests::ROT_THRESHOLD));
       
   600         }
       
   601 
       
   602         if (tmpY<y-tests::ROT_THRESHOLD || tmpY>y+tests::ROT_THRESHOLD){
       
   603             l++;
       
   604             rotTmp.append(tests::debugMessage("Rotation Y: ", tmpY, y, tests::ROT_THRESHOLD));
       
   605         }
       
   606         if (l>tmpL){
       
   607             tmp.append("Rotation failure when in ");
       
   608             tmp.append(tests::orientationAsString(o2));
       
   609             tmp.append("\n");
       
   610             tmp.append(rotTmp);
       
   611         }
       
   612 
       
   613 
       
   614         //magnetometer
       
   615         magge_x[counter-1]=maggeReading->x();
       
   616         magge_y[counter-1]=maggeReading->y();
       
   617         magge_z[counter-1]=maggeReading->z();
       
   618 
       
   619         //        qDebug()<<" magge x="<<magge_x[i-1]<<", y="<<magge_y[i-1]<<", z="<<magge_z[i-1];
       
   620 
       
   621         //compass
       
   622         compass_azimuth[counter-1] = compassReading->azimuth();
       
   623         compass_level[counter-1] = compassReading->calibrationLevel();
       
   624         //        qDebug()<<" compass = "<< compass_azimuth[i-1];
       
   625         //        if (hasZ){
       
   626         //            qDebug()<<" rotation = x "<<rot_x[i-1];
       
   627         //            qDebug()<<" rotation = y "<<rot_y[i-1];
       
   628         //            qDebug()<<" rotation = z "<<rot_z[i-1];
       
   629         //        }
       
   630 
       
   631 
       
   632         if (counter==4){
       
   633             isStationary = true;
       
   634             qDebug()<<"Keep the device on the table on stationary position!:\n";
       
   635             qDebug()<<"Test continues after a while";            
       
   636             QTest::qWait(2000);   // DO NOT REMOVE - does not work without this!
       
   637             isStationary = false;
       
   638         }
       
   639     }
       
   640 
       
   641 
       
   642     //magnetometer: same magnitude, opposite values
       
   643     // x-axis comparison, 1 and 2
       
   644     // y-axis comparison, 0 and 5
       
   645     // z-axis comparison, 3 and 4
       
   646     int rangeIndex = magnetometer.outputRange();
       
   647     qreal threshold = (magnetometer.outputRanges().at(rangeIndex).maximum - magnetometer.outputRanges().at(rangeIndex).minimum)/10;
       
   648 
       
   649     QString msg;
       
   650     if (!tests::testMagge(magge_x[1], magge_x[2], threshold, msg)){
       
   651         tmp.append("Magnetometer failure (x-axis):");
       
   652         tmp.append(msg);
       
   653         msg.clear();
       
   654         j++;
       
   655     }
       
   656     if (!tests::testMagge(magge_y[0], magge_y[5], threshold, msg)){
       
   657         tmp.append("Magnetometer failure (y-axis):");
       
   658         tmp.append(msg);
       
   659         msg.clear();
       
   660         j++;
       
   661     }
       
   662     if (!tests::testMagge(magge_z[3], magge_z[4], threshold, msg)){
       
   663         tmp.append("Magnetometer failure (z-axis):");
       
   664         tmp.append(msg);
       
   665         msg.clear();
       
   666         j++;
       
   667     }
       
   668 
       
   669     //magnetometer: one big value, two small values
       
   670     // x-axis comparison, 1 and 2
       
   671     // y-axis comparison, 0 and 5
       
   672     // z-axis comparison, 3 and 4
       
   673     if (!tests::testMagge2(magge_x[1], magge_y[1], magge_z[1], msg)){
       
   674         tmp.append("Magnetometer x: not bigger than y, z :");
       
   675         tmp.append(msg);
       
   676         msg.clear();
       
   677         j++;
       
   678     }
       
   679     if (!tests::testMagge2(magge_x[2], magge_y[2], magge_z[2], msg)){
       
   680         tmp.append("Magnetometer x: not bigger than y, z :");
       
   681         tmp.append(msg);
       
   682         msg.clear();
       
   683         j++;
       
   684     }
       
   685     if (!tests::testMagge2(magge_y[0], magge_x[0], magge_z[0], msg)){
       
   686         tmp.append("Magnetometer y: not bigger than x, z :");
       
   687         tmp.append(msg);
       
   688         msg.clear();
       
   689         j++;
       
   690     }
       
   691     if (!tests::testMagge2(magge_y[5], magge_x[5], magge_z[5], msg)){
       
   692         tmp.append("Magnetometer y: not bigger than x, z :");
       
   693         tmp.append(msg);
       
   694         msg.clear();
       
   695         j++;
       
   696     }
       
   697     if (!tests::testMagge2(magge_z[3], magge_x[3], magge_y[3], msg)){
       
   698         tmp.append("Magnetometer z: not bigger than x, y :");
       
   699         tmp.append(msg);
       
   700         msg.clear();
       
   701         j++;
       
   702     }
       
   703     if (!tests::testMagge2(magge_z[4], magge_x[4], magge_y[4], msg)){
       
   704         tmp.append("Magnetometer z: not bigger than x, y :");
       
   705         tmp.append(msg);
       
   706         msg.clear();
       
   707         j++;
       
   708     }
       
   709 
       
   710     //rotation
       
   711     if (hasZ){
       
   712         qDebug()<<"Is magnetic north pole rotation sensor's external entity";
       
   713         if (tests::confirm()){
       
   714             for (int i=0; i<6; i++){
       
   715                 if (!(tests::testRot(compass_azimuth[i], rot_z[i], msg))){
       
   716                     tmp.append(msg);
       
   717                     msg.clear();
       
   718                 }
       
   719             }
       
   720         }
       
   721     }
       
   722 
       
   723     // compass: 1&2, 3&4
       
   724     // azimuth will be projected to horizontal plane
       
   725     // top up & top down (5&0): too much variation, NOT tested
       
   726     // left up & right up (1&2): 180 diff
       
   727     // face up & face down (3&4): should be the same
       
   728     // take calibration level into account
       
   729     int index[6]={1,2,3,4};
       
   730 
       
   731     for (int i=0; i<3; i++){
       
   732         if (compass_level[index[i*2]]< 0.1 || compass_level[index[i*2+1]]< 0.1)
       
   733             continue;
       
   734 
       
   735         qreal val1 = compass_azimuth[index[i*2]];
       
   736         qreal val2 = compass_azimuth[index[i*2+1]];
       
   737         //        QString num;
       
   738         //        qDebug()<<" Compass testing val1 = "<<num.setNum(val1)<< " val2 = "<<num.setNum(val2);
       
   739 
       
   740         if (i==0){
       
   741             val1 = ((int)val1+180)%360;
       
   742         }
       
   743 
       
   744         if (!(tests::testCompass(val1, val2, msg))){
       
   745             tmp.append(msg);
       
   746             msg.clear();
       
   747             j++;
       
   748         }
       
   749     }
       
   750 
       
   751     qDebug()<< "Do you have a real compass in use: \n";
       
   752     bool isYes = tests::confirm();
       
   753     if (isYes){
       
   754         qDebug()<<"Put the device in following position, and head it towards compass north:\n";
       
   755         QOrientationReading::Orientation o1 = tests::orientation[4];
       
   756         tests::drawDevice(o1);
       
   757         tests::pressAnyKey();
       
   758         QTest::qWait(50);   // DO NOT REMOVE - does not work without this!
       
   759         qreal azimuth = compassReading->azimuth();
       
   760 
       
   761         if (azimuth>20 && azimuth<340){
       
   762             j++;
       
   763             tmp.append("Instead of being 0, compass north gives ");
       
   764             QString num;
       
   765             num.setNum(azimuth);
       
   766             tmp.append(num);
       
   767             tmp.append("\n");
       
   768         }
       
   769     }
       
   770 
       
   771 
       
   772 
       
   773     QVERIFY2(tmp.size()<2, tmp.toLatin1().data());
       
   774 }
       
   775 
       
   776 
       
   777 void test_manual::testDataRate(){
       
   778     QVERIFY2(dataRateString.size()==0, dataRateString.toLatin1().data());
       
   779     dataRateString.clear();
       
   780 }
       
   781 
       
   782 void test_manual::testOutputRange(){
       
   783     QVERIFY2(dataRangeString.size()==0, dataRangeString.toLatin1().data());
       
   784     dataRangeString.clear();
       
   785 }
       
   786 
       
   787 void test_manual::testResolution(){
       
   788     QVERIFY2(resolutionString.size()==0, resolutionString.toLatin1().data());
       
   789     resolutionString.clear();
       
   790 }
       
   791 
       
   792 
       
   793 
       
   794 QTEST_MAIN(test_manual)
       
   795 
       
   796 #include "test_manual.moc"