From 89fbd66b01bab3eca2ed9591f158f28d6e43e9e2 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Wed, 1 Feb 2012 10:28:51 +1000 Subject: try harder to make sure gesture dont fire too easily some gestures will fire when trying other gestures. Make sure they don't collide and provide false positives as much. Change-Id: I4abd7d9ee876b77a211ae1b46bcc56f4fdc64ec0 Sanity-Review: Qt Sanity Bot Reviewed-by: Lorn Potter --- .../qtsensors/qcoversensorgesturerecognizer.cpp | 7 +- .../qtsensors/qhoversensorgesturerecognizer.cpp | 48 +++--- .../qtsensors/qhoversensorgesturerecognizer.h | 12 +- .../qtsensors/qpickupsensorgesturerecognizer.cpp | 67 +++++++- .../qtsensors/qpickupsensorgesturerecognizer.h | 5 + .../sensorgestures/qtsensors/qshake2recognizer.cpp | 172 ++++++++++----------- .../sensorgestures/qtsensors/qshake2recognizer.h | 33 ++-- .../qtsensors/qturnoversensorgesturerecognizer.cpp | 3 - .../qtsensors/qtwistsensorgesturerecognizer.cpp | 56 +++++-- .../qtsensors/qtwistsensorgesturerecognizer.h | 4 + .../qtsensors/qwhipsensorgesturerecognizer.cpp | 71 +++++++-- .../qtsensors/qwhipsensorgesturerecognizer.h | 6 + .../sensorgestures/shake/qshakerecognizer.cpp | 96 +++++------- .../sensorgestures/shake/qshakerecognizer.h | 30 ++-- 14 files changed, 371 insertions(+), 239 deletions(-) diff --git a/src/plugins/sensorgestures/qtsensors/qcoversensorgesturerecognizer.cpp b/src/plugins/sensorgestures/qtsensors/qcoversensorgesturerecognizer.cpp index 53517117..82a849ed 100644 --- a/src/plugins/sensorgestures/qtsensors/qcoversensorgesturerecognizer.cpp +++ b/src/plugins/sensorgestures/qtsensors/qcoversensorgesturerecognizer.cpp @@ -94,11 +94,12 @@ bool QCoverSensorGestureRecognizer::isActive() } void QCoverSensorGestureRecognizer::proximityChanged() -{ - if ((orientation->reading()->orientation() == QOrientationReading::FaceDown - || orientation->reading()->orientation() == QOrientationReading::FaceUp) +{// look at case of face up->face down->face up. + if ((orientation->reading()->orientation() == QOrientationReading::FaceUp) && proximity->reading()->close()) timer->start(); + else if (proximity->reading()->close()) + timer->stop(); } void QCoverSensorGestureRecognizer::timeout() diff --git a/src/plugins/sensorgestures/qtsensors/qhoversensorgesturerecognizer.cpp b/src/plugins/sensorgestures/qtsensors/qhoversensorgesturerecognizer.cpp index 096d83c4..4717c7d5 100644 --- a/src/plugins/sensorgestures/qtsensors/qhoversensorgesturerecognizer.cpp +++ b/src/plugins/sensorgestures/qtsensors/qhoversensorgesturerecognizer.cpp @@ -55,8 +55,11 @@ QHoverSensorGestureRecognizer::~QHoverSensorGestureRecognizer() void QHoverSensorGestureRecognizer::create() { - light = new QLightSensor(this); - light->connectToBackend(); + proximity = new QProximitySensor(this); + proximity->connectToBackend(); + + irProx = new QIRProximitySensor(this); + irProx->connectToBackend(); timer = new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(timeout())); @@ -66,7 +69,7 @@ void QHoverSensorGestureRecognizer::create() timer2 = new QTimer(this); connect(timer2,SIGNAL(timeout()),this,SLOT(timeout2())); timer2->setSingleShot(true); - timer2->setInterval(3000); + timer2->setInterval(5000); } QString QHoverSensorGestureRecognizer::id() const @@ -76,47 +79,50 @@ QString QHoverSensorGestureRecognizer::id() const bool QHoverSensorGestureRecognizer::start() { - connect(light,SIGNAL(readingChanged()), this,SLOT(lightChanged())); - light->start(); - return light->isActive(); + connect(irProx,SIGNAL(readingChanged()), this,SLOT(proxyChanged())); + proximity->start(); + irProx->start(); + return irProx->isActive(); } bool QHoverSensorGestureRecognizer::stop() { - light->stop(); - disconnect(light,SIGNAL(readingChanged()),this,SLOT(lightChanged())); - return light->isActive(); + proximity->stop(); + irProx->stop(); + disconnect(irProx,SIGNAL(readingChanged()),this,SLOT(proxyChanged())); + return irProx->isActive(); } bool QHoverSensorGestureRecognizer::isActive() { - return light->isActive(); + return irProx->isActive(); } -void QHoverSensorGestureRecognizer::lightChanged() +void QHoverSensorGestureRecognizer::proxyChanged() { - qreal lightReading = light->reading()->lux(); - - int difference = 100 - (lightReading/lastLightReading) * 100; - - if (difference == 0) { + if (proximity->reading()->close()) { + hoverOk = false; + detecting = false; return; } - if (!detecting && difference > 19) { -// if (lightReading < lastLightReading ) { + int refl = irProx->reading()->reflectance() * 100; + + if (!detecting && (refl > 20 && refl < 35)) { detecting = true; timer->start(); timer2->start(); - } else if (hoverOk && detecting && difference < -24) { + + } else if (hoverOk && detecting + && refl == 0) { // went light again after 1 seconds -// qDebug() << "hover"; Q_EMIT hover(); Q_EMIT detected("hover"); hoverOk = false; detecting = false; } - lastLightReading = lightReading; + if (refl == 0) + detecting = false; } void QHoverSensorGestureRecognizer::timeout() diff --git a/src/plugins/sensorgestures/qtsensors/qhoversensorgesturerecognizer.h b/src/plugins/sensorgestures/qtsensors/qhoversensorgesturerecognizer.h index 65384295..d8bf96ba 100644 --- a/src/plugins/sensorgestures/qtsensors/qhoversensorgesturerecognizer.h +++ b/src/plugins/sensorgestures/qtsensors/qhoversensorgesturerecognizer.h @@ -46,7 +46,9 @@ #include #include #include -#include +#include +#include + QT_BEGIN_NAMESPACE class QHoverSensorGestureRecognizer : public QSensorGestureRecognizer @@ -67,17 +69,21 @@ Q_SIGNALS: void hover(); private slots: - void lightChanged(); + void proxyChanged(); void timeout(); void timeout2(); private: - QLightSensor *light; + QProximitySensor *proximity; + QIRProximitySensor *irProx; + QTimer *timer; QTimer *timer2; bool hoverOk; qreal lastLightReading; bool detecting; + qreal detectedHigh; + }; QT_END_NAMESPACE #endif // QHOVERSENSORGESTURERECOGNIZER_H diff --git a/src/plugins/sensorgestures/qtsensors/qpickupsensorgesturerecognizer.cpp b/src/plugins/sensorgestures/qtsensors/qpickupsensorgesturerecognizer.cpp index 0e4ae49f..1a85e242 100644 --- a/src/plugins/sensorgestures/qtsensors/qpickupsensorgesturerecognizer.cpp +++ b/src/plugins/sensorgestures/qtsensors/qpickupsensorgesturerecognizer.cpp @@ -39,12 +39,31 @@ ** ****************************************************************************/ - #include "qpickupsensorgesturerecognizer.h" + +#define _USE_MATH_DEFINES +#include +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288419717 +#endif +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 +#endif + QT_BEGIN_NAMESPACE +inline qreal calcPitch(double Ax, double Ay, double Az) +{ + return (float)-atan2(Ax, sqrt(Ay * Ay + Az * Az)); +} +inline qreal calcRoll(double Ax, double Ay, double Az) +{ + return (float)atan2(Ay, (sqrt(Ax * Ax + Az * Az))); +} + QPickupSensorGestureRecognizer::QPickupSensorGestureRecognizer(QObject *parent) : - QSensorGestureRecognizer(parent),atRest(1),okToSignal(1) + QSensorGestureRecognizer(parent),atRest(1),okToSignal(1), + lastRoll(0) { } @@ -91,7 +110,6 @@ bool QPickupSensorGestureRecognizer::isActive() return active; } -#define kFilteringFactor 0.1 void QPickupSensorGestureRecognizer::accelChanged() { @@ -102,14 +120,21 @@ void QPickupSensorGestureRecognizer::accelChanged() qreal z = accel->reading()->z(); qreal zdiff = pZaxis - z; - if (xdiff < 0.3 && ydiff < .3 && zdiff < .3) { + roll = calc(calcRoll(x, y, z)); + + if (xdiff < 0.7 && ydiff < .7 && zdiff < .7) { atRest = true; } else { - atRest = false; - okToSignal = true; + if (atRest && roll > 15 ) { +// roll = calc(calcRoll(x, y, z)); + atRest = false; + okToSignal = true; + } } - if (atRest && okToSignal && (y > 5.0 && y < 8.9) && (z > 5.0 && z < 7.9)) { + if (atRest&& + okToSignal && (roll < 60 && roll > 15) + && (y > 5.0 && y < 8.9) && (z > 5.0 && z < 7.9)) { if (!timer->isActive()) { timer->start(); } @@ -121,14 +146,26 @@ void QPickupSensorGestureRecognizer::accelChanged() pXaxis = x; pYaxis = y; pZaxis = z; + lastRoll = roll; } void QPickupSensorGestureRecognizer::timeout() { + qreal x = accel->reading()->x(); qreal y = accel->reading()->y(); qreal z = accel->reading()->z(); - if (atRest && (y > 5.0 && y < 8.9) && (z > 5.0 && z < 7.9)) { + qreal thisroll = calc(calcRoll(x, y, z)); + + qreal pitch = calc(calcPitch(x, y, z)); + + qreal difference = thisroll - roll; +//qDebug() << Q_FUNC_INFO << thisroll << pitch; + if (atRest + && (pitch > -6 && pitch < 6) + && (roll < 60 && roll > 15) + && (y > 5.0 && y < 8.9) + && (z > 5.0 && z < 7.9)) { Q_EMIT pickup(); Q_EMIT detected("pickup"); @@ -136,4 +173,18 @@ void QPickupSensorGestureRecognizer::timeout() } } +qreal QPickupSensorGestureRecognizer::calc(qreal yrot) +{ + qreal aG = 1 * sin(yrot); + qreal aK = 1 * cos(yrot); + + yrot = atan2(aG, aK); + if (yrot > M_PI_2) + yrot = M_PI - yrot; + else if (yrot < -M_PI_2) + yrot = -(M_PI + yrot); + + return yrot * 180 / M_PI; +} + QT_END_NAMESPACE diff --git a/src/plugins/sensorgestures/qtsensors/qpickupsensorgesturerecognizer.h b/src/plugins/sensorgestures/qtsensors/qpickupsensorgesturerecognizer.h index 847754e7..65a3f322 100644 --- a/src/plugins/sensorgestures/qtsensors/qpickupsensorgesturerecognizer.h +++ b/src/plugins/sensorgestures/qtsensors/qpickupsensorgesturerecognizer.h @@ -82,6 +82,11 @@ private: qreal pYaxis; qreal pZaxis; + qreal roll; + + qreal calc(qreal yrot); + qreal lastRoll; + }; QT_END_NAMESPACE #endif // QPICKUPSENSORGESTURERECOGNIZER_H diff --git a/src/plugins/sensorgestures/qtsensors/qshake2recognizer.cpp b/src/plugins/sensorgestures/qtsensors/qshake2recognizer.cpp index 07d048ad..cd77582f 100644 --- a/src/plugins/sensorgestures/qtsensors/qshake2recognizer.cpp +++ b/src/plugins/sensorgestures/qtsensors/qshake2recognizer.cpp @@ -43,16 +43,16 @@ #include #include "qshake2recognizer.h" +#include + QT_BEGIN_NAMESPACE QShake2SensorGestureRecognizer::QShake2SensorGestureRecognizer(QObject *parent) : QSensorGestureRecognizer(parent) - , active(0) + , active(0),shaking(0), shakeCount(0), + shakeDirection(QShake2SensorGestureRecognizer::ShakeUndefined) { - pXaxis = 0;nXaxis = 0; - pYaxis = 0;nYaxis = 0; - pZaxis = 0;nZaxis = 0; timerTimeout = 750; } @@ -64,20 +64,11 @@ void QShake2SensorGestureRecognizer::create() { accel = new QAccelerometer(this); accel->connectToBackend(); - timer = new QTimer(this); - - qoutputrangelist outputranges = accel->outputRanges(); - - if (outputranges.count() > 0) - accelRange = (int)(outputranges.at(0).maximum *2) / 9.8; //approx range in g's - else - accelRange = 4; //this should never happen + timer = new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(timeout())); timer->setSingleShot(true); timer->setInterval(timerTimeout); - - } bool QShake2SensorGestureRecognizer::start() @@ -107,100 +98,107 @@ QString QShake2SensorGestureRecognizer::id() const } #define NUMBER_SHAKES 3 +#define THRESHOLD 25 + void QShake2SensorGestureRecognizer::accelChanged() { qreal x = accel->reading()->x(); - qreal xdiff = pXaxis - x; qreal y = accel->reading()->y(); - qreal ydiff = pYaxis - y; qreal z = accel->reading()->z(); - qreal zdiff = pZaxis - z; - - if (abs(xdiff) > (5 * accelRange)) { - - if (shakeDirection == QShake2SensorGestureRecognizer::ShakeUndefined && nXaxis == 0) { - if (xdiff < 0) - shakeDirection = QShake2SensorGestureRecognizer::ShakeLeft; - else - shakeDirection = QShake2SensorGestureRecognizer::ShakeRight; - } - nXaxis++; - if (timer->isActive()) { - timer->stop(); - } - timer->start(); - } - if (abs(ydiff) > (5 * accelRange)) { - if (nYaxis == 0) { - if (shakeDirection == QShake2SensorGestureRecognizer::ShakeUndefined && ydiff < 0) - shakeDirection = QShake2SensorGestureRecognizer::ShakeDown; - else - shakeDirection = QShake2SensorGestureRecognizer::ShakeUp; - } - nYaxis++; - if (timer->isActive()) { - timer->stop(); + currentData.x = x; + currentData.y = y; + currentData.z = z; + + if ( (abs(currentData.x - prevData.x) + || abs(currentData.y - prevData.y) + || abs(currentData.z - prevData.z)) < 1) + return; + + if (!shaking && checkForShake(prevData, currentData, THRESHOLD) && + shakeCount >= NUMBER_SHAKES) { + shaking = true; + shakeCount = 0; + + switch (shakeDirection) { + case QShake2SensorGestureRecognizer::ShakeLeft: + Q_EMIT shakeLeft(); + Q_EMIT detected("shakeLeft"); + break; + case QShake2SensorGestureRecognizer::ShakeRight: + Q_EMIT shakeRight(); + Q_EMIT detected("shakeRight"); + break; + case QShake2SensorGestureRecognizer::ShakeUp: + Q_EMIT shakeUp(); + Q_EMIT detected("shakeUp"); + break; + case QShake2SensorGestureRecognizer::ShakeDown: + Q_EMIT shakeDown(); + Q_EMIT detected("shakeDown"); + break; + default: + break; + }; + + } else if (checkForShake(prevData, currentData, THRESHOLD)) { + + if (shakeCount == 0 && shakeDirection == QShake2SensorGestureRecognizer::ShakeUndefined) { + + int xdiff = currentData.x - prevData.x; + int ydiff = currentData.y - prevData.y; + + int max = qMax(abs(ydiff), abs(xdiff)); + + if (max == abs(xdiff)) { + if (isNegative(xdiff)) + shakeDirection = QShake2SensorGestureRecognizer::ShakeLeft; + else + shakeDirection = QShake2SensorGestureRecognizer::ShakeRight; + + } else if (max == abs(ydiff)) { + if (isNegative(ydiff)) + shakeDirection = QShake2SensorGestureRecognizer::ShakeDown; + else + shakeDirection = QShake2SensorGestureRecognizer::ShakeUp; + } } + shakeCount++; timer->start(); + } - if (abs(zdiff) > (5 * accelRange)) { - nZaxis++; - if (timer->isActive()) { - timer->stop(); - } - timer->start(); - } - if (nYaxis + nZaxis + nXaxis >= NUMBER_SHAKES) { - - switch (shakeDirection) { - case QShake2SensorGestureRecognizer::ShakeLeft: - Q_EMIT shakeLeft(); - Q_EMIT detected("shakeLeft"); - break; - case QShake2SensorGestureRecognizer::ShakeRight: - Q_EMIT shakeRight(); - Q_EMIT detected("shakeRight"); - break; - case QShake2SensorGestureRecognizer::ShakeUp: - Q_EMIT shakeUp(); - Q_EMIT detected("shakeUp"); - break; - case QShake2SensorGestureRecognizer::ShakeDown: - Q_EMIT shakeDown(); - Q_EMIT detected("shakeDown"); - break; - default: - break; - }; - if (timer->isActive()) { - timer->stop(); - } - timeout(); - } - pXaxis = x; - pYaxis = y; - pZaxis = z; + prevData.x = currentData.x; + prevData.y = currentData.y; + prevData.z = currentData.z; + } void QShake2SensorGestureRecognizer::timeout() { - nXaxis = 0; - nYaxis = 0; - nZaxis = 0; + shakeCount = 0; + shaking = false; shakeDirection = QShake2SensorGestureRecognizer::ShakeUndefined; } - -int QShake2SensorGestureRecognizer::thresholdTime() const +bool QShake2SensorGestureRecognizer::checkForShake(ShakeData prevSensorData, ShakeData currentSensorData, qreal threshold) { - return timerTimeout; + double deltaX = qAbs(prevSensorData.x - currentSensorData.x); + double deltaY = qAbs(prevSensorData.y - currentSensorData.y); + double deltaZ = qAbs(prevSensorData.z - currentSensorData.z); + + return (deltaX > threshold + || deltaY > threshold + || deltaZ > threshold); } -void QShake2SensorGestureRecognizer::setThresholdTime(int msec) +bool QShake2SensorGestureRecognizer::isNegative(qreal num) { - timer->setInterval(msec); + if (num < 0) + return true; + return false; } + + QT_END_NAMESPACE diff --git a/src/plugins/sensorgestures/qtsensors/qshake2recognizer.h b/src/plugins/sensorgestures/qtsensors/qshake2recognizer.h index 18423248..ff3de8cf 100644 --- a/src/plugins/sensorgestures/qtsensors/qshake2recognizer.h +++ b/src/plugins/sensorgestures/qtsensors/qshake2recognizer.h @@ -53,6 +53,12 @@ #include QT_BEGIN_NAMESPACE +struct ShakeData { + qreal x; + qreal y; + qreal z; +}; + class QShake2SensorGestureRecognizer : public QSensorGestureRecognizer { Q_OBJECT @@ -77,8 +83,9 @@ public: bool stop(); bool isActive(); - int thresholdTime() const; - void setThresholdTime(int msec); + QTimer *timer; + int timerTimeout; + Q_SIGNALS: void shakeLeft(); @@ -90,27 +97,23 @@ private slots: void accelChanged(); void timeout(); + private: QAccelerometer *accel; - qreal pXaxis; - qreal nXaxis; - - qreal pYaxis; - qreal nYaxis; - - qreal pZaxis; - qreal nZaxis; - - bool detectingState; - QTimer *timer; - int timerTimeout; bool active; - int accelRange; ShakeDirection shakeDirection; + ShakeData prevData; + ShakeData currentData; + + bool checkForShake(ShakeData prevSensorData, ShakeData currentSensorData, qreal threshold); + bool shaking; + int shakeCount; + int threshold; + bool isNegative(qreal num); }; QT_END_NAMESPACE #endif // QSHAKERECOGNIZER_H diff --git a/src/plugins/sensorgestures/qtsensors/qturnoversensorgesturerecognizer.cpp b/src/plugins/sensorgestures/qtsensors/qturnoversensorgesturerecognizer.cpp index 52cc8e6b..17da1a7e 100644 --- a/src/plugins/sensorgestures/qtsensors/qturnoversensorgesturerecognizer.cpp +++ b/src/plugins/sensorgestures/qtsensors/qturnoversensorgesturerecognizer.cpp @@ -118,9 +118,6 @@ void QTurnoverSensorGestureRecognizer::orientationChanged() void QTurnoverSensorGestureRecognizer::isRecognized() { - qDebug() << Q_FUNC_INFO - << isClose << isFaceDown; - if (isClose && isFaceDown) { Q_EMIT turnover(); Q_EMIT detected("turnover"); diff --git a/src/plugins/sensorgestures/qtsensors/qtwistsensorgesturerecognizer.cpp b/src/plugins/sensorgestures/qtsensors/qtwistsensorgesturerecognizer.cpp index f2580b2f..8fdc2efe 100644 --- a/src/plugins/sensorgestures/qtsensors/qtwistsensorgesturerecognizer.cpp +++ b/src/plugins/sensorgestures/qtsensors/qtwistsensorgesturerecognizer.cpp @@ -65,7 +65,7 @@ inline qreal calcRoll(double Ax, double Ay, double Az) } QTwistSensorGestureRecognizer::QTwistSensorGestureRecognizer(QObject *parent) : - QSensorGestureRecognizer(parent), detecting(0), lastDegree(0) + QSensorGestureRecognizer(parent), detecting(0), lastDegree(0), lastX(0) { } @@ -77,6 +77,10 @@ void QTwistSensorGestureRecognizer::create() { accel = new QAccelerometer(this); accel->connectToBackend(); + orientation = new QOrientationSensor(this); + orientation->connectToBackend(); + + timer = new QTimer(this); qoutputrangelist outputranges = accel->outputRanges(); @@ -101,6 +105,7 @@ bool QTwistSensorGestureRecognizer::start() { connect(accel,SIGNAL(readingChanged()),this,SLOT(accelChanged())); active = accel->start(); + orientation->start(); return active; } @@ -110,6 +115,7 @@ bool QTwistSensorGestureRecognizer::stop() disconnect(accel,SIGNAL(readingChanged()),this,SLOT(accelChanged())); active = accel->isActive(); + orientation->stop(); return !active; } @@ -118,8 +124,8 @@ bool QTwistSensorGestureRecognizer::isActive() return active; } -#define RESTING_VARIANCE 10 -#define THRESHOLD_DEGREES 40 +#define RESTING_VARIANCE 20 +#define THRESHOLD_DEGREES 70 void QTwistSensorGestureRecognizer::accelChanged() { @@ -127,33 +133,56 @@ void QTwistSensorGestureRecognizer::accelChanged() qreal y = accel->reading()->y(); qreal z = accel->reading()->z(); - if (abs(x) < 1) - return; - pitch = calcPitch(x, y, z); roll = calcRoll(x, y, z); qreal degrees = calc(pitch); +// qDebug() << Q_FUNC_INFO << degrees << calc(roll) << lastX; + if (xList.count() > 4) { - if (detecting && - abs(lastDegree - degrees) > (accelRange/2)) { - if (lastX < 0) { + if (detecting && (degrees > 0 && lastX < 0 + || degrees < 0 && lastX > 0)) { + // if shake-like: + detecting = false; + timer->stop(); + lastX = degrees; +// qDebug() << Q_FUNC_INFO << "stop detecting"; + } + + if (detecting + && abs(degrees) < RESTING_VARIANCE + && abs(calc(roll)) < RESTING_VARIANCE + && (abs(lastX + degrees) > (degrees / 2)) + ) { + if (lastX < 0 ) { Q_EMIT twistLeft(); Q_EMIT detected("twistLeft"); } else { Q_EMIT twistRight(); Q_EMIT detected("twistRight"); } - detecting = false; - timer->stop(); - lastX = degrees; + // don't give two signals for same gestures + detecting = false; + timer->stop(); + lastX = degrees; } - if (!detecting && abs(degrees) > THRESHOLD_DEGREES) { + if (!detecting && abs(degrees) > THRESHOLD_DEGREES + && calc(roll) < RESTING_VARIANCE) { + detecting = true; timer->start(); lastX = degrees; + lastOrientation = orientation->reading()->orientation(); +// qDebug() << Q_FUNC_INFO << "start detecting" << lastOrientation; + } + + if (detecting && (orientation->reading()->orientation() == QOrientationReading::TopUp + || orientation->reading()->orientation() == QOrientationReading::TopDown)) { + detecting = false; + timer->stop(); + lastX = degrees; } } @@ -167,6 +196,7 @@ void QTwistSensorGestureRecognizer::timeout() { detecting = false; lastX = 0; + lastOrientation = QOrientationReading::Undefined; } qreal QTwistSensorGestureRecognizer::calc(qreal yrot) diff --git a/src/plugins/sensorgestures/qtsensors/qtwistsensorgesturerecognizer.h b/src/plugins/sensorgestures/qtsensors/qtwistsensorgesturerecognizer.h index 89e835fa..45d2d519 100644 --- a/src/plugins/sensorgestures/qtsensors/qtwistsensorgesturerecognizer.h +++ b/src/plugins/sensorgestures/qtsensors/qtwistsensorgesturerecognizer.h @@ -45,6 +45,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QTwistSensorGestureRecognizer : public QSensorGestureRecognizer @@ -71,6 +73,7 @@ private slots: private: QAccelerometer *accel; + QOrientationSensor *orientation; QTimer *timer; int accelRange; qreal lastX; @@ -83,6 +86,7 @@ private: qreal calc(qreal yrot); bool detecting; qreal lastDegree; + QOrientationReading::Orientation lastOrientation; }; QT_END_NAMESPACE #endif // QWFLICKSENSORGESTURERECOGNIZER_H diff --git a/src/plugins/sensorgestures/qtsensors/qwhipsensorgesturerecognizer.cpp b/src/plugins/sensorgestures/qtsensors/qwhipsensorgesturerecognizer.cpp index 94078e47..4869f7e4 100644 --- a/src/plugins/sensorgestures/qtsensors/qwhipsensorgesturerecognizer.cpp +++ b/src/plugins/sensorgestures/qtsensors/qwhipsensorgesturerecognizer.cpp @@ -41,10 +41,26 @@ #include "qwhipsensorgesturerecognizer.h" + +#define _USE_MATH_DEFINES +#include +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288419717 +#endif +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 +#endif + + QT_BEGIN_NAMESPACE +inline qreal calcYaw(double Ax, double Ay, double Az) +{ + return (float)atan2(Az, (sqrt(Ax * Ax + Ay * Ay))); +} + QWhipSensorGestureRecognizer::QWhipSensorGestureRecognizer(QObject *parent) : - QSensorGestureRecognizer(parent), whipIt(0) + QSensorGestureRecognizer(parent), whipIt(0), lastX(0) { } @@ -56,6 +72,10 @@ void QWhipSensorGestureRecognizer::create() { accel = new QAccelerometer(this); accel->connectToBackend(); + + orientation = new QOrientationSensor(this); + orientation->connectToBackend(); + timer = new QTimer(this); qoutputrangelist outputranges = accel->outputRanges(); @@ -80,7 +100,7 @@ bool QWhipSensorGestureRecognizer::start() { connect(accel,SIGNAL(readingChanged()),this,SLOT(accelChanged())); active = accel->start(); - + orientation->start(); return active; } @@ -88,6 +108,7 @@ bool QWhipSensorGestureRecognizer::stop() { accel->stop(); active = accel->isActive(); + orientation->stop(); disconnect(accel,SIGNAL(readingChanged()),this,SLOT(accelChanged())); return !active; } @@ -97,30 +118,42 @@ bool QWhipSensorGestureRecognizer::isActive() return active; } -#define WHIP_THRESHOLD_FACTOR 0.85 -#define WHIP_DETECTION_FACTOR 0.3 +#define WHIP_THRESHOLD_FACTOR 0.95 //37 +#define WHIP_DETECTION_FACTOR 0.3 // 11.7 +#define WHIP_DEGREES 25 void QWhipSensorGestureRecognizer::accelChanged() { qreal x = accel->reading()->x(); + qreal difference = lastX - x; + if (abs(difference) < 1) + return; - if (whipIt) { - qreal difference = lastX - x; + qreal y = accel->reading()->y(); + qreal z = accel->reading()->z(); - if ((!wasNegative && difference > accelRange * WHIP_THRESHOLD_FACTOR) - || (wasNegative && difference < -accelRange * WHIP_THRESHOLD_FACTOR)) { + qreal degreesZ = calc(calcYaw(x,y,z)); + if (whipIt) { + if (((!wasNegative && difference > accelRange * WHIP_THRESHOLD_FACTOR) + || (wasNegative && difference < -accelRange * WHIP_THRESHOLD_FACTOR)) + && abs(degreesZ) < WHIP_DEGREES + && abs(detectedX) < abs(x)) { Q_EMIT whip(); Q_EMIT detected("whip"); whipIt = false; } - } else if (x > (accelRange * WHIP_DETECTION_FACTOR) - || x < -(accelRange * WHIP_DETECTION_FACTOR)) { - //start of gesture + } else if (((difference > 0 && difference < accelRange * WHIP_DETECTION_FACTOR) + || (difference < 0 && difference > -accelRange * WHIP_DETECTION_FACTOR)) + && abs(degreesZ) < WHIP_DEGREES + && orientation->reading()->orientation() != QOrientationReading::FaceUp) { + + detectedX = x; +// start of gesture timer->start(); whipIt = true; - if (lastX > 0) + if (difference > 0) wasNegative = false; else wasNegative = true; @@ -133,4 +166,18 @@ void QWhipSensorGestureRecognizer::timeout() whipIt = false; } +qreal QWhipSensorGestureRecognizer::calc(qreal yrot) +{ + qreal aG = 1 * sin(yrot); + qreal aK = 1 * cos(yrot); + + yrot = atan2(aG, aK); + if (yrot > M_PI_2) + yrot = M_PI - yrot; + else if (yrot < -M_PI_2) + yrot = -(M_PI + yrot); + + return yrot * 180 / M_PI; +} + QT_END_NAMESPACE diff --git a/src/plugins/sensorgestures/qtsensors/qwhipsensorgesturerecognizer.h b/src/plugins/sensorgestures/qtsensors/qwhipsensorgesturerecognizer.h index 962d45fa..fb1b46d6 100644 --- a/src/plugins/sensorgestures/qtsensors/qwhipsensorgesturerecognizer.h +++ b/src/plugins/sensorgestures/qtsensors/qwhipsensorgesturerecognizer.h @@ -45,6 +45,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QWhipSensorGestureRecognizer : public QSensorGestureRecognizer @@ -69,14 +71,18 @@ private slots: void timeout(); private: QAccelerometer *accel; + QOrientationSensor *orientation; QTimer *timer; int accelRange; bool whipIt; bool wasNegative; qreal lastX; + qreal detectedX; + bool active; qreal accelX; + qreal calc(qreal rot); }; QT_END_NAMESPACE diff --git a/src/plugins/sensorgestures/shake/qshakerecognizer.cpp b/src/plugins/sensorgestures/shake/qshakerecognizer.cpp index c291ce18..de784e82 100644 --- a/src/plugins/sensorgestures/shake/qshakerecognizer.cpp +++ b/src/plugins/sensorgestures/shake/qshakerecognizer.cpp @@ -48,11 +48,6 @@ QShakeSensorGestureRecognizer::QShakeSensorGestureRecognizer(QObject *parent) : QSensorGestureRecognizer(parent) , active(0) { - pXaxis = 0;nXaxis = 0; - pYaxis = 0;nYaxis = 0; - pZaxis = 0;nZaxis = 0; - timerTimeout = 1500; - } QShakeSensorGestureRecognizer::~QShakeSensorGestureRecognizer() @@ -63,7 +58,6 @@ void QShakeSensorGestureRecognizer::create() { accel = new QAccelerometer(this); accel->connectToBackend(); - timer = new QTimer(this); qoutputrangelist outputranges = accel->outputRanges(); @@ -72,10 +66,6 @@ void QShakeSensorGestureRecognizer::create() else accelRange = 4; //this should never happen - connect(timer,SIGNAL(timeout()),this,SLOT(timeout())); - timer->setSingleShot(true); - timer->setInterval(timerTimeout); - connect(accel,SIGNAL(readingChanged()),this,SLOT(accelChanged())); } @@ -105,63 +95,53 @@ QString QShakeSensorGestureRecognizer::id() const } #define NUMBER_SHAKES 3 +#define THRESHOLD 25 + void QShakeSensorGestureRecognizer::accelChanged() { qreal x = accel->reading()->x(); - qreal xdiff = pXaxis - x; qreal y = accel->reading()->y(); - qreal ydiff = pYaxis - y; qreal z = accel->reading()->z(); - qreal zdiff = pZaxis - z; - - if (abs(xdiff) > (5 * accelRange)) { - nXaxis++; - if (timer->isActive()) { - timer->stop(); - } - timer->start(); - } - if (abs(ydiff) > (5 * accelRange)) { - nYaxis++; - if (timer->isActive()) { - timer->stop(); - } - timer->start(); + + currentData.x = x; + currentData.y = y; + currentData.z = z; + + if ((abs(currentData.x - prevData.x) + || abs(currentData.y - prevData.y) + || abs(currentData.z - prevData.z)) < 1) + return; + + + if (!shaking && checkForShake(prevData, currentData, THRESHOLD) && + shakeCount >= NUMBER_SHAKES) { + shaking = true; + shakeCount = 0; + + Q_EMIT shake(); + Q_EMIT detected("shake"); + + } else if (checkForShake(prevData, currentData, THRESHOLD)) { + shakeCount++; + } else if (!checkForShake(prevData, currentData, 200)) { + shakeCount = 0; + shaking = false; } - if (abs(zdiff) > (5 * accelRange)) { - nZaxis++; - if (timer->isActive()) { - timer->stop(); - } - timer->start(); - } - - if (nYaxis + nZaxis + nXaxis >= NUMBER_SHAKES) { - Q_EMIT shake(); - Q_EMIT detected("shake"); - if (timer->isActive()) { - timer->stop(); - } - timeout(); - } - pXaxis = x; - pYaxis = y; - pZaxis = z; -} -void QShakeSensorGestureRecognizer::timeout() -{ - nXaxis = 0; - nYaxis = 0; - nZaxis = 0; + prevData.x = currentData.x; + prevData.y = currentData.y; + prevData.z = currentData.z; } -int QShakeSensorGestureRecognizer::thresholdTime() const -{ - return timerTimeout; -} -void QShakeSensorGestureRecognizer::setThresholdTime(int msec) +bool QShakeSensorGestureRecognizer::checkForShake(AccelData prevSensorData, AccelData currentSensorData, qreal threshold) { - timer->setInterval(msec); + double deltaX = qAbs(prevSensorData.x - currentSensorData.x); + double deltaY = qAbs(prevSensorData.y - currentSensorData.y); + double deltaZ = qAbs(prevSensorData.z - currentSensorData.z); + + return (deltaX > threshold && deltaY > threshold) || + (deltaX > threshold && deltaZ > threshold) || + (deltaY > threshold && deltaZ > threshold); } + diff --git a/src/plugins/sensorgestures/shake/qshakerecognizer.h b/src/plugins/sensorgestures/shake/qshakerecognizer.h index 4292c664..dfba26b3 100644 --- a/src/plugins/sensorgestures/shake/qshakerecognizer.h +++ b/src/plugins/sensorgestures/shake/qshakerecognizer.h @@ -51,6 +51,12 @@ #include + struct AccelData { + qreal x; + qreal y; + qreal z; +}; + class QShakeSensorGestureRecognizer : public QSensorGestureRecognizer { Q_OBJECT @@ -67,32 +73,24 @@ public: bool stop(); bool isActive(); - int thresholdTime() const; - void setThresholdTime(int msec); - Q_SIGNALS: void shake(); private slots: void accelChanged(); - void timeout(); private: QAccelerometer *accel; + bool active; + int accelRange; - qreal pXaxis; - qreal nXaxis; - - qreal pYaxis; - qreal nYaxis; + AccelData prevData; + AccelData currentData; - qreal pZaxis; - qreal nZaxis; + bool checkForShake(AccelData prevSensorData, AccelData currentSensorData, qreal threshold); + bool shaking; + int shakeCount; + int threshold; - bool detectingState; - QTimer *timer; - int timerTimeout; - bool active; - int accelRange; }; #endif // QSHAKERECOGNIZER_H -- cgit v1.2.3