// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "services/device/generic_sensor/orientation_util.h" #include <cmath> #include <numbers> #include "base/check_op.h" #include "base/numerics/angle_conversions.h" #include "services/device/generic_sensor/generic_sensor_consts.h" namespace { // Returns orientation angles from a rotation matrix, such that the angles are // according to spec http://dev.w3.org/geo/api/spec-source-orientation.html}. // // It is assumed the rotation matrix transforms a 3D column vector from device // coordinate system to the world's coordinate system. // // In particular we compute the decomposition of a given rotation matrix r such // that // r = rz(alpha) * rx(beta) * ry(gamma) // where rz, rx and ry are rotation matrices around z, x and y axes in the world // coordinate reference frame respectively. The reference frame consists of // three orthogonal axes x, y, z where x points East, y points north and z // points upwards perpendicular to the ground plane. The computed angles alpha, // beta and gamma are in degrees and clockwise-positive when viewed along the // positive direction of the corresponding axis. Except for the special case // when the beta angle is +-pi/2 these angles uniquely define the orientation of // a mobile device in 3D space. The alpha-beta-gamma representation resembles // the yaw-pitch-roll convention used in vehicle dynamics, however it does not // exactly match it. One of the differences is that the 'pitch' angle beta is // allowed to be within [-pi, pi). A mobile device with pitch angle greater than // pi/2 could correspond to a user lying down and looking upward at the screen. // // r is a 9 element rotation matrix: // r[ 0] r[ 1] r[ 2] // r[ 3] r[ 4] r[ 5] // r[ 6] r[ 7] r[ 8] // // alpha_in_radians: rotation around the z axis, in [0, 2*pi) // beta_in_radians: rotation around the x axis, in [-pi, pi) // gamma_in_radians: rotation around the y axis, in [-pi/2, pi/2) void ComputeOrientationEulerAnglesInRadiansFromRotationMatrix( const std::vector<double>& r, double* alpha_in_radians, double* beta_in_radians, double* gamma_in_radians) { … } } // namespace namespace device { void ComputeOrientationEulerAnglesFromRotationMatrix( const std::vector<double>& r, double* alpha_in_degrees, double* beta_in_degrees, double* gamma_in_degrees) { … } } // namespace device