1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "genericrotationsensor.h"
5#include <QDebug>
6#include <qmath.h>
7
8char const * const genericrotationsensor::id("generic.rotation");
9
10genericrotationsensor::genericrotationsensor(QSensor *sensor)
11 : QSensorBackend(sensor)
12{
13 accelerometer = new QAccelerometer(this);
14 accelerometer->addFilter(filter: this);
15 accelerometer->connectToBackend();
16
17 setReading<QRotationReading>(&m_reading);
18 setDataRates(accelerometer);
19
20 QRotationSensor * const rotationSensor = qobject_cast<QRotationSensor *>(object: sensor);
21 if (rotationSensor)
22 rotationSensor->setHasZ(false);
23}
24
25void genericrotationsensor::start()
26{
27 accelerometer->setDataRate(sensor()->dataRate());
28 accelerometer->setAlwaysOn(sensor()->isAlwaysOn());
29 accelerometer->start();
30 if (!accelerometer->isActive())
31 sensorStopped();
32 if (accelerometer->isBusy())
33 sensorBusy();
34}
35
36void genericrotationsensor::stop()
37{
38 accelerometer->stop();
39}
40
41bool genericrotationsensor::filter(QSensorReading *reading)
42{
43 QAccelerometerReading *ar = qobject_cast<QAccelerometerReading*>(object: reading);
44 qreal pitch = 0;
45 qreal roll = 0;
46
47 qreal x = ar->x();
48 qreal y = ar->y();
49 qreal z = ar->z();
50
51 // Note that the formula used come from this document:
52 // http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf
53 pitch = qRadiansToDegrees(radians: qAtan(v: y / qSqrt(v: x * x + z * z)));
54 roll = qRadiansToDegrees(radians: qAtan(v: x / qSqrt(v: y * y + z * z)));
55 // Roll is a left-handed rotation but we need right-handed rotation
56 roll = -roll;
57
58 // We need to fix up roll to the (-180,180] range required.
59 // Check for negative theta values and apply an offset as required.
60 // Note that theta is defined as the angle of the Z axis relative
61 // to gravity (see referenced document). It's negative when the
62 // face of the device points downward.
63 qreal theta = qRadiansToDegrees(radians: qAtan(v: qSqrt(v: x * x + y * y) / z));
64 if (theta < 0) {
65 if (roll > 0)
66 roll = 180 - roll;
67 else
68 roll = -180 - roll;
69 }
70
71 m_reading.setTimestamp(ar->timestamp());
72 m_reading.setFromEuler(x: pitch, y: roll, z: 0);
73 newReadingAvailable();
74 return false;
75}
76
77

source code of qtsensors/src/plugins/sensors/generic/genericrotationsensor.cpp