absolute_orientation_euler_angles_fusion_algorithm_using_accelerometer_and_magnetometer_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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. #include <cmath>
  5. #include "base/memory/raw_ptr.h"
  6. #include "base/memory/ref_counted.h"
  7. #include "base/test/task_environment.h"
  8. #include "services/device/generic_sensor/absolute_orientation_euler_angles_fusion_algorithm_using_accelerometer_and_magnetometer.h"
  9. #include "services/device/generic_sensor/fake_platform_sensor_fusion.h"
  10. #include "services/device/generic_sensor/generic_sensor_consts.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. #include "ui/gfx/geometry/angle_conversions.h"
  13. namespace device {
  14. namespace {
  15. class
  16. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest
  17. : public testing::Test {
  18. public:
  19. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest() {
  20. auto fusion_algorithm = std::make_unique<
  21. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometer>();
  22. fusion_algorithm_ = fusion_algorithm.get();
  23. fake_fusion_sensor_ = base::MakeRefCounted<FakePlatformSensorFusion>(
  24. std::move(fusion_algorithm));
  25. fusion_algorithm_->set_fusion_sensor(fake_fusion_sensor_.get());
  26. EXPECT_EQ(2UL, fusion_algorithm_->source_types().size());
  27. }
  28. void VerifyAbsoluteOrientationEulerAngles(double gravity_x,
  29. double gravity_y,
  30. double gravity_z,
  31. double geomagnetic_x,
  32. double geomagnetic_y,
  33. double geomagnetic_z,
  34. double expected_alpha_in_degrees,
  35. double expected_beta_in_degrees,
  36. double expected_gamma_in_degrees) {
  37. SensorReading gravity_reading;
  38. gravity_reading.accel.x = gravity_x;
  39. gravity_reading.accel.y = gravity_y;
  40. gravity_reading.accel.z = gravity_z;
  41. SensorReading geomagnetic_reading;
  42. geomagnetic_reading.accel.x = geomagnetic_x;
  43. geomagnetic_reading.accel.y = geomagnetic_y;
  44. geomagnetic_reading.accel.z = geomagnetic_z;
  45. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::ACCELEROMETER,
  46. gravity_reading,
  47. true /* sensor_reading_success */);
  48. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::MAGNETOMETER,
  49. geomagnetic_reading,
  50. true /* sensor_reading_success */);
  51. SensorReading fused_reading;
  52. EXPECT_TRUE(fusion_algorithm_->GetFusedData(
  53. mojom::SensorType::ACCELEROMETER, &fused_reading));
  54. EXPECT_NEAR(expected_alpha_in_degrees,
  55. fused_reading.orientation_euler.z /* alpha */, kEpsilon);
  56. EXPECT_NEAR(expected_beta_in_degrees,
  57. fused_reading.orientation_euler.x /* beta */, kEpsilon);
  58. EXPECT_NEAR(expected_gamma_in_degrees,
  59. fused_reading.orientation_euler.y /* gamma */, kEpsilon);
  60. }
  61. protected:
  62. base::test::TaskEnvironment task_environment_;
  63. scoped_refptr<FakePlatformSensorFusion> fake_fusion_sensor_;
  64. raw_ptr<
  65. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometer>
  66. fusion_algorithm_;
  67. };
  68. } // namespace
  69. TEST_F(
  70. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  71. AccelerometerReadingNotChanged) {
  72. SensorReading reading;
  73. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::ACCELEROMETER,
  74. reading,
  75. true /* sensor_reading_success */);
  76. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::MAGNETOMETER,
  77. reading,
  78. true /* sensor_reading_success */);
  79. SensorReading fused_reading;
  80. EXPECT_FALSE(fusion_algorithm_->GetFusedData(mojom::SensorType::MAGNETOMETER,
  81. &fused_reading));
  82. }
  83. TEST_F(
  84. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  85. NoAccelerometerReading) {
  86. SensorReading reading;
  87. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::ACCELEROMETER,
  88. reading,
  89. false /* sensor_reading_success */);
  90. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::MAGNETOMETER,
  91. reading,
  92. true /* sensor_reading_success */);
  93. SensorReading fused_reading;
  94. EXPECT_FALSE(fusion_algorithm_->GetFusedData(mojom::SensorType::ACCELEROMETER,
  95. &fused_reading));
  96. }
  97. TEST_F(
  98. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  99. NoMagnetometerReading) {
  100. SensorReading reading;
  101. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::ACCELEROMETER,
  102. reading,
  103. true /* sensor_reading_success */);
  104. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::MAGNETOMETER,
  105. reading,
  106. false /* sensor_reading_success */);
  107. SensorReading fused_reading;
  108. EXPECT_FALSE(fusion_algorithm_->GetFusedData(mojom::SensorType::ACCELEROMETER,
  109. &fused_reading));
  110. }
  111. TEST_F(
  112. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  113. GravityLessThanTenPercentOfNormalValue) {
  114. SensorReading gravity_reading;
  115. gravity_reading.accel.x = 0.1;
  116. gravity_reading.accel.y = 0.2;
  117. gravity_reading.accel.z = 0.3;
  118. SensorReading geomagnetic_reading;
  119. geomagnetic_reading.accel.x = 1.0;
  120. geomagnetic_reading.accel.y = 2.0;
  121. geomagnetic_reading.accel.z = 3.0;
  122. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::ACCELEROMETER,
  123. gravity_reading,
  124. true /* sensor_reading_success */);
  125. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::MAGNETOMETER,
  126. geomagnetic_reading,
  127. true /* sensor_reading_success */);
  128. SensorReading fused_reading;
  129. EXPECT_FALSE(fusion_algorithm_->GetFusedData(mojom::SensorType::ACCELEROMETER,
  130. &fused_reading));
  131. }
  132. TEST_F(
  133. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  134. NormalHIsTooSmall) {
  135. SensorReading gravity_reading;
  136. gravity_reading.accel.x = 1.0;
  137. gravity_reading.accel.y = 1.0;
  138. gravity_reading.accel.z = 1.0;
  139. SensorReading geomagnetic_reading;
  140. geomagnetic_reading.accel.x = 1.0;
  141. geomagnetic_reading.accel.y = 1.0;
  142. geomagnetic_reading.accel.z = 1.0;
  143. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::ACCELEROMETER,
  144. gravity_reading,
  145. true /* sensor_reading_success */);
  146. fake_fusion_sensor_->SetSensorReading(mojom::SensorType::MAGNETOMETER,
  147. geomagnetic_reading,
  148. true /* sensor_reading_success */);
  149. SensorReading fused_reading;
  150. EXPECT_FALSE(fusion_algorithm_->GetFusedData(mojom::SensorType::ACCELEROMETER,
  151. &fused_reading));
  152. }
  153. TEST_F(
  154. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  155. Identity) {
  156. double gravity_x = 0.0;
  157. double gravity_y = 0.0;
  158. double gravity_z = 1.0;
  159. double geomagnetic_x = 0.0;
  160. double geomagnetic_y = 1.0;
  161. double geomagnetic_z = 0.0;
  162. double expected_alpha_in_degrees = 0.0;
  163. double expected_beta_in_degrees = 0.0;
  164. double expected_gamma_in_degrees = 0.0;
  165. VerifyAbsoluteOrientationEulerAngles(
  166. gravity_x, gravity_y, gravity_z, geomagnetic_x, geomagnetic_y,
  167. geomagnetic_z, expected_alpha_in_degrees, expected_beta_in_degrees,
  168. expected_gamma_in_degrees);
  169. }
  170. TEST_F(
  171. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  172. BetaIs45Degrees) {
  173. double gravity_x = 0.0;
  174. double gravity_y = std::sin(gfx::DegToRad(45.0));
  175. double gravity_z = std::cos(gfx::DegToRad(45.0));
  176. double geomagnetic_x = 0.0;
  177. double geomagnetic_y = 1.0;
  178. double geomagnetic_z = 0.0;
  179. double expected_alpha_in_degrees = 0.0;
  180. double expected_beta_in_degrees = 45.0;
  181. double expected_gamma_in_degrees = 0.0;
  182. VerifyAbsoluteOrientationEulerAngles(
  183. gravity_x, gravity_y, gravity_z, geomagnetic_x, geomagnetic_y,
  184. geomagnetic_z, expected_alpha_in_degrees, expected_beta_in_degrees,
  185. expected_gamma_in_degrees);
  186. }
  187. TEST_F(
  188. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  189. GammaIs45Degrees) {
  190. double gravity_x = -std::sin(gfx::DegToRad(45.0));
  191. double gravity_y = 0.0;
  192. double gravity_z = std::cos(gfx::DegToRad(45.0));
  193. double geomagnetic_x = 0.0;
  194. double geomagnetic_y = 1.0;
  195. double geomagnetic_z = 0.0;
  196. double expected_alpha_in_degrees = 0.0;
  197. double expected_beta_in_degrees = 0.0;
  198. double expected_gamma_in_degrees = 45.0;
  199. VerifyAbsoluteOrientationEulerAngles(
  200. gravity_x, gravity_y, gravity_z, geomagnetic_x, geomagnetic_y,
  201. geomagnetic_z, expected_alpha_in_degrees, expected_beta_in_degrees,
  202. expected_gamma_in_degrees);
  203. }
  204. TEST_F(
  205. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  206. AlphaIs45Degrees) {
  207. double gravity_x = 0.0;
  208. double gravity_y = 0.0;
  209. double gravity_z = 1.0;
  210. double geomagnetic_x = std::sin(gfx::DegToRad(45.0));
  211. double geomagnetic_y = std::cos(gfx::DegToRad(45.0));
  212. double geomagnetic_z = 0.0;
  213. double expected_alpha_in_degrees = 45.0;
  214. double expected_beta_in_degrees = 0.0;
  215. double expected_gamma_in_degrees = 0.0;
  216. VerifyAbsoluteOrientationEulerAngles(
  217. gravity_x, gravity_y, gravity_z, geomagnetic_x, geomagnetic_y,
  218. geomagnetic_z, expected_alpha_in_degrees, expected_beta_in_degrees,
  219. expected_gamma_in_degrees);
  220. }
  221. TEST_F(
  222. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  223. GimbalLock) {
  224. double gravity_x = 0.0;
  225. double gravity_y = 1.0;
  226. double gravity_z = 0.0;
  227. double geomagnetic_x = std::sin(gfx::DegToRad(45.0));
  228. double geomagnetic_y = 0.0;
  229. double geomagnetic_z = -std::cos(gfx::DegToRad(45.0));
  230. // Favor Alpha instead of Gamma.
  231. double expected_alpha_in_degrees = 45.0;
  232. double expected_beta_in_degrees = 90.0;
  233. double expected_gamma_in_degrees = 0.0;
  234. VerifyAbsoluteOrientationEulerAngles(
  235. gravity_x, gravity_y, gravity_z, geomagnetic_x, geomagnetic_y,
  236. geomagnetic_z, expected_alpha_in_degrees, expected_beta_in_degrees,
  237. expected_gamma_in_degrees);
  238. }
  239. TEST_F(
  240. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  241. BetaIsGreaterThan90Degrees) {
  242. double gravity_x = 0.0;
  243. double gravity_y = std::cos(gfx::DegToRad(45.0));
  244. double gravity_z = -std::sin(gfx::DegToRad(45.0));
  245. double geomagnetic_x = 0.0;
  246. double geomagnetic_y = 0.0;
  247. double geomagnetic_z = -1.0;
  248. double expected_alpha_in_degrees = 0.0;
  249. double expected_beta_in_degrees = 135.0;
  250. double expected_gamma_in_degrees = 0.0;
  251. VerifyAbsoluteOrientationEulerAngles(
  252. gravity_x, gravity_y, gravity_z, geomagnetic_x, geomagnetic_y,
  253. geomagnetic_z, expected_alpha_in_degrees, expected_beta_in_degrees,
  254. expected_gamma_in_degrees);
  255. }
  256. TEST_F(
  257. AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometerTest,
  258. GammaIsMinus90Degrees) {
  259. double gravity_x = -1.0;
  260. double gravity_y = 0.0;
  261. double gravity_z = 0.0;
  262. double geomagnetic_x = 0.0;
  263. double geomagnetic_y = 1.0;
  264. double geomagnetic_z = 0.0;
  265. double expected_alpha_in_degrees = 180.0;
  266. double expected_beta_in_degrees = -180.0;
  267. double expected_gamma_in_degrees = -90.0;
  268. VerifyAbsoluteOrientationEulerAngles(
  269. gravity_x, gravity_y, gravity_z, geomagnetic_x, geomagnetic_y,
  270. geomagnetic_z, expected_alpha_in_degrees, expected_beta_in_degrees,
  271. expected_gamma_in_degrees);
  272. }
  273. } // namespace device