examples/sensors/test_manual/test_manual.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 25 Aug 2010 15:49:42 +0300
changeset 0 876b1a06bc25
permissions -rw-r--r--
Revision: 201033

/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QObject>
#include <QTest>
#include <QDebug>
#include <QSettings>
#include <iostream>


#include <qsensor.h>
#include <qorientationsensor.h>
#include <qaccelerometer.h>
#include <qrotationsensor.h>
#include <qmagnetometer.h>
#include <qcompass.h>
#include "sensorslotclass.h"

QTM_USE_NAMESPACE

        static QOrientationReading::Orientation o2;
static QOrientationSensor orientationSensor;
static QAccelerometer accelerometer;
static QRotationSensor rotationSensor;
static QAccelerometerReading* acceReading;
static QRotationReading* rotReading;
static QMagnetometer magnetometer;
static QMagnetometerReading* maggeReading;
static QCompass compass;
static QCompassReading* compassReading;


static QString dataRateString;
static QString dataRangeString;
static QString resolutionString;
static int counter;
static bool isStationary = false;

///////////////////////////////////////////
//cpp file
///////////////////////////////////////////


SensorSlotClass::SensorSlotClass()
{
    int rateMax =0;
    connect(&orientationSensor, SIGNAL(readingChanged()), this, SLOT(slotOrientationData()));
    if (orientationSensor.availableDataRates().size()>0){
        rateMax = orientationSensor.availableDataRates().at(0).second;
        orientationSensor.setDataRate(rateMax);
    }
    orientationSensor.start();
    connect(&accelerometer, SIGNAL(readingChanged()), this, SLOT(slotAccelerationData()));
    if (accelerometer.availableDataRates().size()>0){
        rateMax = accelerometer.availableDataRates().at(0).second;
        accelerometer.setDataRate(rateMax);
    }
    accelerometer.start();
    connect(&rotationSensor, SIGNAL(readingChanged()), this, SLOT(slotRotationData()));
    if (rotationSensor.availableDataRates().size()>0){
        rateMax = rotationSensor.availableDataRates().at(0).second;
        rotationSensor.setDataRate(rateMax);
    }
    rotationSensor.start();
    magnetometer.setProperty("returnGeoValues", true);
    connect(&magnetometer, SIGNAL(readingChanged()), this, SLOT(slotMagnetometerData()));
    if (magnetometer.availableDataRates().size()>0){
        rateMax = magnetometer.availableDataRates().at(0).second;
        magnetometer.setDataRate(rateMax);
    }
    magnetometer.start();

    connect(&compass, SIGNAL(readingChanged()), this, SLOT(slotCompassData()));
    if (compass.availableDataRates().size()>0){
        rateMax = compass.availableDataRates().at(0).second;
        compass.setDataRate(rateMax);
    }
    compass.start();

    m_x=0; m_y=0; m_z=0;
}

SensorSlotClass::~SensorSlotClass(){
    disconnect(&compass);
    compass.stop();

    disconnect(&orientationSensor);
    orientationSensor.stop();

    disconnect(&rotationSensor);
    rotationSensor.stop();

    disconnect(&magnetometer);
    magnetometer.stop();

    disconnect(&accelerometer);
    accelerometer.stop();

}


void SensorSlotClass::slotOrientationData(){
    o2 = orientationSensor.reading()->orientation();
    checkRange(&orientationSensor, o2);
    checkRate(&orientationSensor, m_orientationTimestamp);
}


void SensorSlotClass::slotAccelerationData(){

    acceReading = accelerometer.reading();
    checkRange(&accelerometer, acceReading->x());
    checkRange(&accelerometer, acceReading->y());
    checkRange(&accelerometer, acceReading->z());

    checkRate(&accelerometer, m_accelerometerTimestamp);

    if (isStationary) checkResolution(&accelerometer, acceReading);

}

void SensorSlotClass::slotRotationData(){
    rotReading = rotationSensor.reading();
    checkRange(&rotationSensor, rotReading->x());
    checkRange(&rotationSensor, rotReading->y());
    checkRange(&rotationSensor, rotReading->z());

    checkRate(&rotationSensor, m_rotationTimestamp);
}

void SensorSlotClass::slotMagnetometerData(){

    maggeReading = magnetometer.reading();
    checkRange(&magnetometer, maggeReading->x());
    checkRange(&magnetometer, maggeReading->y());
    checkRange(&magnetometer, maggeReading->z());

    checkRate(&magnetometer, m_magnetometerTimestamp);

}

void SensorSlotClass::slotCompassData(){
    compassReading = compass.reading();
    checkRange(&compass, (qreal)compassReading->azimuth());

    checkRate(&compass, m_compassTimestamp);
}


void SensorSlotClass::checkRange(QSensor* sensor, qreal value){
    qreal min = sensor->outputRanges().at(sensor->outputRange()).minimum;
    qreal max = sensor->outputRanges().at(sensor->outputRange()).maximum;

    if (min>value || value> max){
        QString num;
        dataRangeString.append(sensor->type());
        dataRangeString.append(": range=[");
        dataRangeString.append(num.setNum(min));
        dataRangeString.append(",");
        dataRangeString.append(num.setNum(max));
        dataRangeString.append("], value =");
        dataRangeString.append(num.setNum(value));
        dataRangeString.append("\n");
    }

}


void SensorSlotClass::checkRate(QSensor* sensor, int &exTimestamp){
    int timestamp = sensor->reading()->timestamp();
    int diff = timestamp - exTimestamp;
    int rate = sensor->dataRate();
    if (rate==0) return;
    if (diff < (1000/rate)*0.9){
        dataRateString.append(sensor->type());
        dataRateString.append(": rate=");
        dataRateString.append(sensor->dataRate());
        dataRateString.append(", measured rate=");
        dataRateString.append(1000/diff);
        dataRateString.append("\n");
    }

    exTimestamp = timestamp;
}


void SensorSlotClass::checkResolution(QSensor* sensor, QAccelerometerReading* reading){
    qreal x = reading->x();
    qreal y = reading->y();
    qreal z = reading->z();


    qreal resolution = sensor->outputRanges().at(sensor->outputRange()).accuracy;

    if (m_x!=0){
        qreal diff = qAbs(x-m_x);
        checkDiff(diff, resolution, ": x resolution=");
        diff = qAbs(y-m_y);
        checkDiff(diff, resolution, ": y resolution=");
        diff = qAbs(z-m_z);
        checkDiff(diff, resolution, ": z resolution=");
    }
    m_x = x;
    m_y = y;
    m_z = z;

}

void SensorSlotClass::checkDiff(qreal diff, qreal resolution, QString msg){
    if (diff==0) return;
    qreal resolutionMax = 3*resolution;


    if (qAbs(diff)<resolution || qAbs(diff)>resolutionMax){
        QString num;
        resolutionString.append("\n");
        resolutionString.append("accelerometer:");
        resolutionString.append(msg);
        num.setNum(resolution);
        resolutionString.append(num);
        resolutionString.append("!=");
        num.setNum(qAbs(diff));
        resolutionString.append(num);
    }

}



namespace tests{

    static QOrientationReading::Orientation orientation[] = {
        QOrientationReading::TopUp,
        QOrientationReading::TopDown,
        QOrientationReading::LeftUp,
        QOrientationReading::RightUp,
        QOrientationReading::FaceUp,
        QOrientationReading::FaceDown
    };


    static const float GRAVITY_EARTH = 9.80665;
    static const float THRESHOLD = GRAVITY_EARTH/4;

    static void pressAnyKey()
    {
        std::string value;
        qDebug()<< "Press any key: \n";
        std::getline(std::cin, value);
    }


    static QString debugMessage(QString title, qreal expected, qreal measured, qreal threshold){
        QString msg;
        msg.append(title);
        QString num;
        num.setNum(measured);
        msg.append(num);
        msg.append(" was not in range [");
        num.setNum(expected - threshold);
        msg.append(num);
        msg.append(",");
        num.setNum(expected + threshold);
        msg.append(num);
        msg.append("]");
        msg.append("\n");
        return msg;
    }


    static void drawDevice(QOrientationReading::Orientation orientation){
        switch (orientation) {
        case QOrientationReading::TopUp:
            std::cout<<"    ___________\n";
            std::cout<<"    | _______ |\n";
            std::cout<<"    | |     | |\n";
            std::cout<<"    | |     | |\n";
            std::cout<<"    | |_____| |\n";
            std::cout<<"    | _______ |\n";
            std::cout<<"    | |_|_|_| |\n";
            std::cout<<"    | |_|_|_| |\n";
            std::cout<<"    | |_|_|_| |\n";
            std::cout<<"    |_________|\n";
            std::cout<< "Top up \n"; break;
            break;
        case QOrientationReading::TopDown:
            std::cout<<"     _________ \n";
            std::cout<<"    | _______ |\n";
            std::cout<<"    | |_|_|_| |\n";
            std::cout<<"    | |_|_|_| |\n";
            std::cout<<"    | |_|_|_| |\n";
            std::cout<<"    | _______ |\n";
            std::cout<<"    | |     | |\n";
            std::cout<<"    | |     | |\n";
            std::cout<<"    | |_____| |\n";
            std::cout<<"    |_________|\n";
            std::cout<<"Top down \n"; break;
        case QOrientationReading::LeftUp:
            std::cout<<"     _________________\n";
            std::cout<<"    | _______ ______  |\n";
            std::cout<<"    | |_|_|_| |     | |\n";
            std::cout<<"    | |_|_|_| |     | |\n";
            std::cout<<"    | |_|_|_| |_____| |\n";
            std::cout<<"    |_________________|\n";
            std::cout<<"Left up  \n"; break;
        case QOrientationReading::RightUp:
            std::cout<<"     _________________\n";
            std::cout<<"    | _______ ______  |\n";
            std::cout<<"    | |     | |_|_|_| |\n";
            std::cout<<"    | |     | |_|_|_| |\n";
            std::cout<<"    | |_____| |_|_|_| |\n";
            std::cout<<"    |_________________|\n";
            std::cout<<"Right up \n"; break;
        case QOrientationReading::FaceUp:
            std::cout<<"     _________\n";
            std::cout<<"    |  ' ' '  |\n";
            std::cout<<"    |_________|\n";
            std::cout<<"Face up  \n"; break;
        case QOrientationReading::FaceDown:
            std::cout<<"     _________\n";
            std::cout<<"    |         |\n";
            std::cout<<"    |__._._.__|\n";
            std::cout<<"Face down\n"; break;
        case QOrientationReading::Undefined: std::cout<<"Undefined\n"; break;
        default: std::cout<<"Invalid enum value\n";
        }
    }


    static const char* orientationAsString(QOrientationReading::Orientation orientation){
        switch (orientation) {
        case QOrientationReading::TopUp:     return "Top up   ";
        case QOrientationReading::TopDown:   return "Top down ";
        case QOrientationReading::LeftUp:    return  "Left up  ";
        case QOrientationReading::RightUp:   return "Right up ";
        case QOrientationReading::FaceUp:    return "Face up  ";
        case QOrientationReading::FaceDown:  return "Face down";
        case QOrientationReading::Undefined: return "Undefined";
        default: return "Invalid enum value";
        }
    }


    static qreal acce_array[6][3]=
    {
        {0, tests::GRAVITY_EARTH, 0},
        {0, -tests::GRAVITY_EARTH, 0},
        {-tests::GRAVITY_EARTH, 0, 0},
        {tests::GRAVITY_EARTH, 0, 0},
        {0, 0, tests::GRAVITY_EARTH},
        {0, 0, -tests::GRAVITY_EARTH}};


    static qreal rot_array[6][2]=
    {
        {90,0},
        {-90, 0},
        {0,90},
        {0,-90},
        {0, 0},
        {0, 180}};

    static const qreal ROT_THRESHOLD = 20;


    static bool confirm()
    {
        std::string value;
        while (true){
            qDebug()<< "Answer(y/N):";
            std::getline(std::cin, value);
            if (value.compare("Y")==0 || value.compare("y")==0 ) return true;
            if (value.compare("N")==0 || value.compare("n")==0 || value.compare("")==0 || value.compare(" ")==0 || value.compare("\n")==0) return false;
        }
    }

    static bool testMagge(qreal val1, qreal val2, qreal threshold, QString &msg){
        bool isOk = true;

        if (val1+val2>threshold){
            isOk = false;
            QString num;
            msg.append(num.setNum(val1));
            msg.append("!=");
            msg.append(num.setNum(val2));
            msg.append("\n");
        }
        return isOk;
    }



    static bool testMagge2(qreal valBig, qreal valSmall1, qreal valSmall2, QString &msg){
        bool isOk = true;
        if (qAbs(valBig)< qAbs(valSmall1) || qAbs(valBig)< qAbs(valSmall2)){
            isOk = false;
            QString num;
            msg.append(num.setNum(valBig));
            msg.append(",");
            msg.append(num.setNum(valSmall1));
            msg.append(",");
            msg.append(num.setNum(valSmall2));
            msg.append("\n");
        }
        return isOk;
    }


    static bool testCompass(qreal val1, qreal val2, QString &msg){
        bool isOk = true;
        int threshold = 30;


        if (qAbs(val1 - val2)> threshold){
            if (val1>360-threshold)
                if ((360 - val1 + val2)< threshold) return isOk;
            if (val2>360-threshold)
                if ((360 - val2 + val1)< threshold) return isOk;
            isOk = false;
            msg.append("Compass failure:");
            QString num;
            msg.append(num.setNum(val1));
            msg.append("!=");
            msg.append(num.setNum(val2));
            msg.append("\n");
        }
        return isOk;
    }


    static bool testRot(qreal azimuth, qreal rotZ, QString &msg){
        bool isOk = true;


        qreal tmpAzimuth = rotZ>0 ? 360 -rotZ : -rotZ;
        int threshold = 30;


        if (qAbs(azimuth - tmpAzimuth)> threshold){
            if (tmpAzimuth> 360-threshold)
                if ((360 - tmpAzimuth + azimuth)< threshold) return isOk;
            if (azimuth> 360-threshold)
                if ((360 - azimuth + tmpAzimuth)< threshold) return isOk;

            isOk=false;
            msg.append("Rot/compass comparison failed: ");
            QString num;
            msg.append(num.setNum(azimuth));
            msg.append("!=");
            msg.append(num.setNum(tmpAzimuth));
            msg.append("\n");
        }

        return isOk;
    }



}


class test_manual: public QObject{
    Q_OBJECT
    private slots:
    void testOrientation();
    void testDataRate();
    void testOutputRange();
    void testResolution();
};


void test_manual::testOrientation()

{

    SensorSlotClass slotClass;

    bool hasZ = rotationSensor.property("hasZ").toBool();

    int j=0,k=0,l=0;


    qreal magge_x[6];
    qreal magge_y[6];
    qreal magge_z[6];
    qreal rot_x[6];
    qreal rot_y[6];
    qreal rot_z[6];
    qreal compass_azimuth[6];
    qreal compass_level[6];

    QString tmp("\n");


    for (; counter<7; counter++){
        qDebug()<<"Put the device in following position, try to preserve compass direction:\n";
        if (counter==4) qDebug()<<"Put the device on the table on stationary position!:\n";
        QOrientationReading::Orientation o1 = tests::orientation[counter%6];
        tests::drawDevice(o1);
        tests::pressAnyKey();
        QTest::qWait(50);   // DO NOT REMOVE - does not work without this!

        if (counter==0) continue;     //prevent from first UNDEFINED VALUE


        if (o1!=o2){
            j++;
            tmp.append("Orientation: expected/measured: \n");
            tmp.append(tests::orientationAsString(o1));
            tmp.append("!=");
            tmp.append(tests::orientationAsString(o2));
            tmp.append("\n");
        }


        //acceleration
        qreal tmpX = tests::acce_array[counter%6][0];
        qreal tmpY = tests::acce_array[counter%6][1];
        qreal tmpZ = tests::acce_array[counter%6][2];
        qreal x = acceReading->x();
        qreal y = acceReading->y();
        qreal z = acceReading->z();

        QString accTmp;
        int tmpK = k;
        if (qAbs(x-tmpX)>tests::THRESHOLD){
            k++;
            accTmp.append(tests::debugMessage("Acceleration X: ",tmpX, x, tests::THRESHOLD));
        }

        if (qAbs(y-tmpY)>tests::THRESHOLD){
            k++;
            accTmp.append(tests::debugMessage("Acceleration Y: ",tmpY, y, tests::THRESHOLD));
        }

        if (qAbs(z-tmpZ)>tests::THRESHOLD){
            k++;
            accTmp.append(tests::debugMessage("Acceleration Z: ",tmpZ, z, tests::THRESHOLD));
        }
        if (k>tmpK){
            tmp.append("Acceleration failure when in ");
            tmp.append(tests::orientationAsString(o2));
            tmp.append("\n");
            tmp.append(accTmp);
        }

        //rotation
        QString rotTmp;
        tmpX = tests::rot_array[counter%6][0];
        tmpY = tests::rot_array[counter%6][1];
        x = rotReading->x();
        y = rotReading->y();
        if (hasZ){
            rot_x[counter-1]=rotReading->x();
            rot_y[counter-1]=rotReading->y();
            rot_z[counter-1]=rotReading->z();
        }
        int tmpL = l;
        // not as straight-forward
        if (qAbs(x-tmpX)>tests::ROT_THRESHOLD){
            l++;
            rotTmp.append(tests::debugMessage("Rotation X: ", tmpX, x, tests::ROT_THRESHOLD));
        }

        if (tmpY<y-tests::ROT_THRESHOLD || tmpY>y+tests::ROT_THRESHOLD){
            l++;
            rotTmp.append(tests::debugMessage("Rotation Y: ", tmpY, y, tests::ROT_THRESHOLD));
        }
        if (l>tmpL){
            tmp.append("Rotation failure when in ");
            tmp.append(tests::orientationAsString(o2));
            tmp.append("\n");
            tmp.append(rotTmp);
        }


        //magnetometer
        magge_x[counter-1]=maggeReading->x();
        magge_y[counter-1]=maggeReading->y();
        magge_z[counter-1]=maggeReading->z();

        //        qDebug()<<" magge x="<<magge_x[i-1]<<", y="<<magge_y[i-1]<<", z="<<magge_z[i-1];

        //compass
        compass_azimuth[counter-1] = compassReading->azimuth();
        compass_level[counter-1] = compassReading->calibrationLevel();
        //        qDebug()<<" compass = "<< compass_azimuth[i-1];
        //        if (hasZ){
        //            qDebug()<<" rotation = x "<<rot_x[i-1];
        //            qDebug()<<" rotation = y "<<rot_y[i-1];
        //            qDebug()<<" rotation = z "<<rot_z[i-1];
        //        }


        if (counter==4){
            isStationary = true;
            qDebug()<<"Keep the device on the table on stationary position!:\n";
            qDebug()<<"Test continues after a while";            
            QTest::qWait(2000);   // DO NOT REMOVE - does not work without this!
            isStationary = false;
        }
    }


    //magnetometer: same magnitude, opposite values
    // x-axis comparison, 1 and 2
    // y-axis comparison, 0 and 5
    // z-axis comparison, 3 and 4
    int rangeIndex = magnetometer.outputRange();
    qreal threshold = (magnetometer.outputRanges().at(rangeIndex).maximum - magnetometer.outputRanges().at(rangeIndex).minimum)/10;

    QString msg;
    if (!tests::testMagge(magge_x[1], magge_x[2], threshold, msg)){
        tmp.append("Magnetometer failure (x-axis):");
        tmp.append(msg);
        msg.clear();
        j++;
    }
    if (!tests::testMagge(magge_y[0], magge_y[5], threshold, msg)){
        tmp.append("Magnetometer failure (y-axis):");
        tmp.append(msg);
        msg.clear();
        j++;
    }
    if (!tests::testMagge(magge_z[3], magge_z[4], threshold, msg)){
        tmp.append("Magnetometer failure (z-axis):");
        tmp.append(msg);
        msg.clear();
        j++;
    }

    //magnetometer: one big value, two small values
    // x-axis comparison, 1 and 2
    // y-axis comparison, 0 and 5
    // z-axis comparison, 3 and 4
    if (!tests::testMagge2(magge_x[1], magge_y[1], magge_z[1], msg)){
        tmp.append("Magnetometer x: not bigger than y, z :");
        tmp.append(msg);
        msg.clear();
        j++;
    }
    if (!tests::testMagge2(magge_x[2], magge_y[2], magge_z[2], msg)){
        tmp.append("Magnetometer x: not bigger than y, z :");
        tmp.append(msg);
        msg.clear();
        j++;
    }
    if (!tests::testMagge2(magge_y[0], magge_x[0], magge_z[0], msg)){
        tmp.append("Magnetometer y: not bigger than x, z :");
        tmp.append(msg);
        msg.clear();
        j++;
    }
    if (!tests::testMagge2(magge_y[5], magge_x[5], magge_z[5], msg)){
        tmp.append("Magnetometer y: not bigger than x, z :");
        tmp.append(msg);
        msg.clear();
        j++;
    }
    if (!tests::testMagge2(magge_z[3], magge_x[3], magge_y[3], msg)){
        tmp.append("Magnetometer z: not bigger than x, y :");
        tmp.append(msg);
        msg.clear();
        j++;
    }
    if (!tests::testMagge2(magge_z[4], magge_x[4], magge_y[4], msg)){
        tmp.append("Magnetometer z: not bigger than x, y :");
        tmp.append(msg);
        msg.clear();
        j++;
    }

    //rotation
    if (hasZ){
        qDebug()<<"Is magnetic north pole rotation sensor's external entity";
        if (tests::confirm()){
            for (int i=0; i<6; i++){
                if (!(tests::testRot(compass_azimuth[i], rot_z[i], msg))){
                    tmp.append(msg);
                    msg.clear();
                }
            }
        }
    }

    // compass: 1&2, 3&4
    // azimuth will be projected to horizontal plane
    // top up & top down (5&0): too much variation, NOT tested
    // left up & right up (1&2): 180 diff
    // face up & face down (3&4): should be the same
    // take calibration level into account
    int index[6]={1,2,3,4};

    for (int i=0; i<3; i++){
        if (compass_level[index[i*2]]< 0.1 || compass_level[index[i*2+1]]< 0.1)
            continue;

        qreal val1 = compass_azimuth[index[i*2]];
        qreal val2 = compass_azimuth[index[i*2+1]];
        //        QString num;
        //        qDebug()<<" Compass testing val1 = "<<num.setNum(val1)<< " val2 = "<<num.setNum(val2);

        if (i==0){
            val1 = ((int)val1+180)%360;
        }

        if (!(tests::testCompass(val1, val2, msg))){
            tmp.append(msg);
            msg.clear();
            j++;
        }
    }

    qDebug()<< "Do you have a real compass in use: \n";
    bool isYes = tests::confirm();
    if (isYes){
        qDebug()<<"Put the device in following position, and head it towards compass north:\n";
        QOrientationReading::Orientation o1 = tests::orientation[4];
        tests::drawDevice(o1);
        tests::pressAnyKey();
        QTest::qWait(50);   // DO NOT REMOVE - does not work without this!
        qreal azimuth = compassReading->azimuth();

        if (azimuth>20 && azimuth<340){
            j++;
            tmp.append("Instead of being 0, compass north gives ");
            QString num;
            num.setNum(azimuth);
            tmp.append(num);
            tmp.append("\n");
        }
    }



    QVERIFY2(tmp.size()<2, tmp.toLatin1().data());
}


void test_manual::testDataRate(){
    QVERIFY2(dataRateString.size()==0, dataRateString.toLatin1().data());
    dataRateString.clear();
}

void test_manual::testOutputRange(){
    QVERIFY2(dataRangeString.size()==0, dataRangeString.toLatin1().data());
    dataRangeString.clear();
}

void test_manual::testResolution(){
    QVERIFY2(resolutionString.size()==0, resolutionString.toLatin1().data());
    resolutionString.clear();
}



QTEST_MAIN(test_manual)

#include "test_manual.moc"