1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QDebug>
#include <QTimer>
#include "qshakerecognizer.h"
QShakeSensorGestureRecognizer::QShakeSensorGestureRecognizer(QObject *parent)
: QSensorGestureRecognizer(parent)
, timerTimeout(450)
, active(0)
, shaking(0)
, shakeCount(0)
{
}
QShakeSensorGestureRecognizer::~QShakeSensorGestureRecognizer()
{
}
void QShakeSensorGestureRecognizer::create()
{
accel = new QAccelerometer(this);
accel->connectToBackend();
accel->setDataRate(50);
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
connect(accel,SIGNAL(readingChanged()),this,SLOT(accelChanged()));
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));
timer->setSingleShot(true);
timer->setInterval(timerTimeout);
}
bool QShakeSensorGestureRecognizer::start()
{
active = accel->start();
return active;
}
bool QShakeSensorGestureRecognizer::stop()
{
accel->stop();
active = accel->isActive();
return !active;
}
bool QShakeSensorGestureRecognizer::isActive()
{
return active;
}
QString QShakeSensorGestureRecognizer::id() const
{
return QString("QtSensors.shake");
}
#define NUMBER_SHAKES 3
#define THRESHOLD 25
void QShakeSensorGestureRecognizer::accelChanged()
{
qreal x = accel->reading()->x();
qreal y = accel->reading()->y();
qreal z = accel->reading()->z();
currentData.x = x;
currentData.y = y;
currentData.z = z;
if (qAbs(prevData.x - currentData.x) < 1
&& qAbs(prevData.y - currentData.y) < 1
&& qAbs(prevData.z - currentData.z) < 1) {
prevData.x = currentData.x;
prevData.y = currentData.y;
prevData.z = currentData.z;
return;
}
bool wasShake = checkForShake(prevData, currentData, THRESHOLD);
if (!shaking && wasShake &&
shakeCount >= NUMBER_SHAKES) {
shaking = true;
shakeCount = 0;
Q_EMIT shake();
Q_EMIT detected("shake");
} else if (wasShake) {
shakeCount++;
if (shakeCount > NUMBER_SHAKES) {
timer->start();
}
}
prevData.x = currentData.x;
prevData.y = currentData.y;
prevData.z = currentData.z;
}
void QShakeSensorGestureRecognizer::timeout()
{
shakeCount = 0;
shaking = false;
}
bool QShakeSensorGestureRecognizer::checkForShake(AccelData prevSensorData, AccelData currentSensorData, qreal threshold)
{
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);
}
|