1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtSensors module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40
41#include "qwhipsensorgesturerecognizer.h"
42#include "qtsensorgesturesensorhandler.h"
43
44#include <QtCore/qmath.h>
45
46#define TIMER_TIMEOUT 850
47
48QT_BEGIN_NAMESPACE
49
50QWhipSensorGestureRecognizer::QWhipSensorGestureRecognizer(QObject *parent)
51 : QSensorGestureRecognizer(parent),
52 orientationReading(0),
53 accelRange(0),
54 active(0),
55 lastX(0),
56 lastY(0),
57 lastZ(0),
58 detecting(0),
59 whipOk(0)
60 , lastTimestamp(0)
61 , timerActive(0)
62 , lapsedTime(0)
63{
64}
65
66QWhipSensorGestureRecognizer::~QWhipSensorGestureRecognizer()
67{
68}
69
70void QWhipSensorGestureRecognizer::create()
71{
72}
73
74QString QWhipSensorGestureRecognizer::id() const
75{
76 return QString("QtSensors.whip");
77}
78
79bool QWhipSensorGestureRecognizer::start()
80{
81 if (QtSensorGestureSensorHandler::instance()->startSensor(sensor: QtSensorGestureSensorHandler::Accel)) {
82 if (QtSensorGestureSensorHandler::instance()->startSensor(sensor: QtSensorGestureSensorHandler::Orientation)) {
83 accelRange = QtSensorGestureSensorHandler::instance()->accelRange;
84 active = true;
85 connect(sender: QtSensorGestureSensorHandler::instance(),SIGNAL(orientationReadingChanged(QOrientationReading*)),
86 receiver: this,SLOT(orientationReadingChanged(QOrientationReading*)));
87
88 connect(sender: QtSensorGestureSensorHandler::instance(),SIGNAL(accelReadingChanged(QAccelerometerReading*)),
89 receiver: this,SLOT(accelChanged(QAccelerometerReading*)));
90 } else {
91 QtSensorGestureSensorHandler::instance()->stopSensor(sensor: QtSensorGestureSensorHandler::Accel);
92 active = false;
93 }
94 } else {
95 active = false;
96 }
97 lastTimestamp = 0;
98 timerActive = false;
99 lapsedTime = 0;
100 return active;
101}
102
103bool QWhipSensorGestureRecognizer::stop()
104{
105 QtSensorGestureSensorHandler::instance()->stopSensor(sensor: QtSensorGestureSensorHandler::Accel);
106 QtSensorGestureSensorHandler::instance()->stopSensor(sensor: QtSensorGestureSensorHandler::Orientation);
107 disconnect(sender: QtSensorGestureSensorHandler::instance(),SIGNAL(orientationReadingChanged(QOrientationReading*)),
108 receiver: this,SLOT(orientationReadingChanged(QOrientationReading*)));
109
110 disconnect(sender: QtSensorGestureSensorHandler::instance(),SIGNAL(accelReadingChanged(QAccelerometerReading*)),
111 receiver: this,SLOT(accelChanged(QAccelerometerReading*)));
112 active = false;
113 return active;
114}
115
116bool QWhipSensorGestureRecognizer::isActive()
117{
118 return active;
119}
120
121void QWhipSensorGestureRecognizer::orientationReadingChanged(QOrientationReading *reading)
122{
123 orientationReading = reading;
124}
125
126#define WHIP_FACTOR -11.0
127#define WHIP_WIGGLE_FACTOR 0.35
128
129void QWhipSensorGestureRecognizer::accelChanged(QAccelerometerReading *reading)
130{
131 const qreal x = reading->x();
132 const qreal y = reading->y();
133 qreal z = reading->z();
134
135 quint64 timestamp = reading->timestamp();
136
137 if (zList.count() > 4)
138 zList.removeLast();
139
140 qreal averageZ = 0;
141 Q_FOREACH (qreal az, zList) {
142 averageZ += az;
143 }
144// averageZ += z;
145 averageZ /= zList.count();
146
147 zList.insert(i: 0,t: z);
148
149 if (orientationReading == 0)
150 return;
151 //// very hacky
152 if (orientationReading->orientation() == QOrientationReading::FaceUp) {
153 z = z - 9.8;
154 }
155
156 const qreal diffX = lastX - x;
157 const qreal diffY = lastY - y;
158
159 if (detecting && whipMap.count() > 5 && whipMap.at(i: 5) == true) {
160 checkForWhip();
161 }
162
163 if (whipMap.count() > 5)
164 whipMap.removeLast();
165
166 if (negativeList.count() > 5)
167 negativeList.removeLast();
168
169 if (z < WHIP_FACTOR
170 && qAbs(t: diffX) > -(accelRange * .1285)//-5.0115
171 && qAbs(t: lastX) < 7
172 && qAbs(t: x) < 7) {
173 whipMap.insert(i: 0,t: true);
174 if (!detecting && !timerActive) {
175 timerActive = true;
176 detecting = true;
177 }
178 } else {
179 whipMap.insert(i: 0,t: false);
180 }
181
182 // check if shaking
183 if ((((x < 0 && lastX > 0) || (x > 0 && lastX < 0))
184 && qAbs(t: diffX) > (accelRange * 0.7)) //27.3
185 || (((y < 0 && lastY > 0) || (y > 0 && lastY < 0))
186 && qAbs(t: diffY) > (accelRange * 0.7))) {
187 negativeList.insert(i: 0,t: true);
188 } else {
189 negativeList.insert(i: 0,t: false);
190 }
191
192 lastX = x;
193 lastY = y;
194 lastZ = z;
195
196 if (timerActive && lastTimestamp > 0)
197 lapsedTime += (timestamp - lastTimestamp )/1000;
198
199 if (timerActive && lapsedTime >= TIMER_TIMEOUT) {
200 timeout();
201 }
202}
203
204void QWhipSensorGestureRecognizer::timeout()
205{
206 detecting = false;
207}
208
209
210void QWhipSensorGestureRecognizer::checkForWhip()
211{
212 whipOk = false;
213
214 int check = 0;
215 Q_FOREACH (qreal az, zList) {
216 if (az < -10)
217 check++;
218 }
219 if (check >= 4)
220 whipOk = true;
221 else
222 return;
223
224 if (whipOk) {
225 bool ok = true;
226 for (int i = 0; i < negativeList.count() - 1; i++) {
227 if (negativeList.at(i)) {
228 ok = false;
229 }
230 }
231 if (ok) {
232 Q_EMIT whip();
233 Q_EMIT detected("whip");
234 }
235 detecting = false;
236 whipMap.clear();
237 timerActive = false;
238 }
239}
240
241QT_END_NAMESPACE
242

source code of qtsensors/src/plugins/sensorgestures/qtsensors/qwhipsensorgesturerecognizer.cpp