1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <cmath>
6
7 #include "base/memory/ref_counted.h"
8 #include "base/numerics/math_constants.h"
9 #include "base/test/task_environment.h"
10 #include "services/device/generic_sensor/fake_platform_sensor_fusion.h"
11 #include "services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace device {
15
16 namespace {
17
18 class RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest
19 : public testing::Test {
20 public:
RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest()21 RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest() {
22 auto fusion_algorithm = std::make_unique<
23 RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometer>();
24 fusion_algorithm_ = fusion_algorithm.get();
25 fake_fusion_sensor_ = base::MakeRefCounted<FakePlatformSensorFusion>(
26 std::move(fusion_algorithm));
27 fusion_algorithm_->set_fusion_sensor(fake_fusion_sensor_.get());
28 EXPECT_EQ(1UL, fusion_algorithm_->source_types().size());
29 }
30
VerifyRelativeOrientationEulerAngles(double acceleration_x,double acceleration_y,double acceleration_z,double expected_beta_in_degrees,double expected_gamma_in_degrees)31 void VerifyRelativeOrientationEulerAngles(double acceleration_x,
32 double acceleration_y,
33 double acceleration_z,
34 double expected_beta_in_degrees,
35 double expected_gamma_in_degrees) {
36 SensorReading reading;
37 reading.accel.x = acceleration_x;
38 reading.accel.y = acceleration_y;
39 reading.accel.z = acceleration_z;
40
41 fake_fusion_sensor_->SetSensorReading(mojom::SensorType::ACCELEROMETER,
42 reading,
43 true /* sensor_reading_success */);
44
45 SensorReading fused_reading;
46 EXPECT_TRUE(fusion_algorithm_->GetFusedData(
47 mojom::SensorType::ACCELEROMETER, &fused_reading));
48
49 EXPECT_TRUE(
50 std::isnan(fused_reading.orientation_euler.z.value() /* alpha */));
51 EXPECT_DOUBLE_EQ(expected_beta_in_degrees,
52 fused_reading.orientation_euler.x /* beta */);
53 EXPECT_DOUBLE_EQ(expected_gamma_in_degrees,
54 fused_reading.orientation_euler.y /* gamma */);
55 }
56
57 protected:
58 base::test::TaskEnvironment task_environment_;
59 scoped_refptr<FakePlatformSensorFusion> fake_fusion_sensor_;
60 RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometer*
61 fusion_algorithm_;
62 };
63
64 } // namespace
65
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,NoAccelerometerReading)66 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
67 NoAccelerometerReading) {
68 SensorReading reading;
69 fake_fusion_sensor_->SetSensorReading(mojom::SensorType::ACCELEROMETER,
70 reading,
71 false /* sensor_reading_success */);
72 SensorReading fused_reading;
73 EXPECT_FALSE(fusion_algorithm_->GetFusedData(mojom::SensorType::ACCELEROMETER,
74 &fused_reading));
75 }
76
77 // Tests a device resting flat.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,NeutralOrientation)78 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
79 NeutralOrientation) {
80 double acceleration_x = 0.0;
81 double acceleration_y = 0.0;
82 double acceleration_z = base::kMeanGravityDouble;
83
84 double expected_beta_in_degrees = 0.0;
85 double expected_gamma_in_degrees = 0.0;
86
87 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
88 acceleration_z, expected_beta_in_degrees,
89 expected_gamma_in_degrees);
90 }
91
92 // Tests an upside-down device, such that the W3C boundary [-180, 180) causes
93 // the beta value to become negative.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,UpsideDown)94 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
95 UpsideDown) {
96 double acceleration_x = 0.0;
97 double acceleration_y = 0.0;
98 double acceleration_z = -base::kMeanGravityDouble;
99
100 double expected_beta_in_degrees = -180.0;
101 double expected_gamma_in_degrees = 0.0;
102
103 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
104 acceleration_z, expected_beta_in_degrees,
105 expected_gamma_in_degrees);
106 }
107
108 // Tests for positive beta value before the device is completely upside-down.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,BeforeUpsideDownBoundary)109 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
110 BeforeUpsideDownBoundary) {
111 double acceleration_x = 0.0;
112 double acceleration_y = -base::kMeanGravityDouble / 2.0;
113 double acceleration_z = -base::kMeanGravityDouble / 2.0;
114
115 double expected_beta_in_degrees = 135.0;
116 double expected_gamma_in_degrees = 0.0;
117
118 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
119 acceleration_z, expected_beta_in_degrees,
120 expected_gamma_in_degrees);
121 }
122
123 // Tests a device lying on its top-edge.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,TopEdge)124 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
125 TopEdge) {
126 double acceleration_x = 0.0;
127 double acceleration_y = base::kMeanGravityDouble;
128 double acceleration_z = 0.0;
129
130 double expected_beta_in_degrees = -90.0;
131 double expected_gamma_in_degrees = 0.0;
132
133 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
134 acceleration_z, expected_beta_in_degrees,
135 expected_gamma_in_degrees);
136 }
137
138 // Tests before a device is completely on its top-edge.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,BeforeTopEdgeBoundary)139 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
140 BeforeTopEdgeBoundary) {
141 double acceleration_x = 0.0;
142 double acceleration_y = base::kMeanGravityDouble / 2.0;
143 double acceleration_z = base::kMeanGravityDouble / 2.0;
144
145 double expected_beta_in_degrees = -45.0;
146 double expected_gamma_in_degrees = 0.0;
147
148 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
149 acceleration_z, expected_beta_in_degrees,
150 expected_gamma_in_degrees);
151 }
152
153 // Tests a device lying on its bottom-edge.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,BottomEdge)154 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
155 BottomEdge) {
156 double acceleration_x = 0.0;
157 double acceleration_y = -base::kMeanGravityDouble;
158 double acceleration_z = 0.0;
159
160 double expected_beta_in_degrees = 90.0;
161 double expected_gamma_in_degrees = 0.0;
162
163 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
164 acceleration_z, expected_beta_in_degrees,
165 expected_gamma_in_degrees);
166 }
167
168 // Tests before a device is completely on its bottom-edge.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,BeforeBottomEdgeBoundary)169 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
170 BeforeBottomEdgeBoundary) {
171 double acceleration_x = 0.0;
172 double acceleration_y = -base::kMeanGravityDouble / 2.0;
173 double acceleration_z = base::kMeanGravityDouble / 2.0;
174
175 double expected_beta_in_degrees = 45.0;
176 double expected_gamma_in_degrees = 0.0;
177
178 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
179 acceleration_z, expected_beta_in_degrees,
180 expected_gamma_in_degrees);
181 }
182
183 // Tests a device lying on its left-edge.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,LeftEdge)184 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
185 LeftEdge) {
186 double acceleration_x = -base::kMeanGravityDouble;
187 double acceleration_y = 0.0;
188 double acceleration_z = 0.0;
189
190 double expected_beta_in_degrees = 0.0;
191 double expected_gamma_in_degrees = -90.0;
192
193 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
194 acceleration_z, expected_beta_in_degrees,
195 expected_gamma_in_degrees);
196 }
197
198 // Tests for negative gamma value before the device is completely on its left
199 // side.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,BeforeLeftEdgeBoundary)200 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
201 BeforeLeftEdgeBoundary) {
202 double acceleration_x = -base::kMeanGravityDouble / std::sqrt(2.0);
203 double acceleration_y = 0.0;
204 double acceleration_z = base::kMeanGravityDouble / std::sqrt(2.0);
205
206 double expected_beta_in_degrees = 0.0;
207 double expected_gamma_in_degrees = -45.0;
208
209 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
210 acceleration_z, expected_beta_in_degrees,
211 expected_gamma_in_degrees);
212 }
213
214 // Tests a device lying on its right-edge, such that the W3C boundary [-90, 90)
215 // causes the gamma value to become negative.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,RightEdge)216 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
217 RightEdge) {
218 double acceleration_x = base::kMeanGravityDouble;
219 double acceleration_y = 0.0;
220 double acceleration_z = 0.0;
221
222 double expected_beta_in_degrees = 0.0;
223 double expected_gamma_in_degrees = -90.0;
224
225 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
226 acceleration_z, expected_beta_in_degrees,
227 expected_gamma_in_degrees);
228 }
229
230 // Tests for positive gamma value before the device is completely on its right
231 // side.
TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,BeforeRightEdgeBoundary)232 TEST_F(RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometerTest,
233 BeforeRightEdgeBoundary) {
234 double acceleration_x = base::kMeanGravityDouble / std::sqrt(2.0);
235 double acceleration_y = 0.0;
236 double acceleration_z = base::kMeanGravityDouble / std::sqrt(2.0);
237
238 double expected_beta_in_degrees = 0.0;
239 double expected_gamma_in_degrees = 45.0;
240
241 VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
242 acceleration_z, expected_beta_in_degrees,
243 expected_gamma_in_degrees);
244 }
245
246 } // namespace device
247