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 | |
48 | QT_BEGIN_NAMESPACE |
49 | |
50 | QWhipSensorGestureRecognizer::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 | |
66 | QWhipSensorGestureRecognizer::~QWhipSensorGestureRecognizer() |
67 | { |
68 | } |
69 | |
70 | void QWhipSensorGestureRecognizer::create() |
71 | { |
72 | } |
73 | |
74 | QString QWhipSensorGestureRecognizer::id() const |
75 | { |
76 | return QString("QtSensors.whip" ); |
77 | } |
78 | |
79 | bool 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 | |
103 | bool 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 | |
116 | bool QWhipSensorGestureRecognizer::isActive() |
117 | { |
118 | return active; |
119 | } |
120 | |
121 | void QWhipSensorGestureRecognizer::orientationReadingChanged(QOrientationReading *reading) |
122 | { |
123 | orientationReading = reading; |
124 | } |
125 | |
126 | #define WHIP_FACTOR -11.0 |
127 | #define WHIP_WIGGLE_FACTOR 0.35 |
128 | |
129 | void 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 | |
204 | void QWhipSensorGestureRecognizer::timeout() |
205 | { |
206 | detecting = false; |
207 | } |
208 | |
209 | |
210 | void 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 | |
241 | QT_END_NAMESPACE |
242 | |