OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/device_orientation/accelerometer_mac.h" | 5 #include "content/browser/device_orientation/accelerometer_mac.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "content/browser/device_orientation/orientation.h" | 10 #include "content/browser/device_orientation/orientation.h" |
11 #include "third_party/sudden_motion_sensor/sudden_motion_sensor_mac.h" | 11 #include "third_party/sudden_motion_sensor/sudden_motion_sensor_mac.h" |
12 | 12 |
13 namespace device_orientation { | 13 namespace device_orientation { |
14 | 14 |
15 // Create a AccelerometerMac object and return NULL if no valid sensor found. | 15 // Create a AccelerometerMac object and return NULL if no valid sensor found. |
16 DataFetcher* AccelerometerMac::Create() { | 16 DataFetcher* AccelerometerMac::Create() { |
17 scoped_ptr<AccelerometerMac> accelerometer(new AccelerometerMac); | 17 scoped_ptr<AccelerometerMac> accelerometer(new AccelerometerMac); |
18 return accelerometer->Init() ? accelerometer.release() : NULL; | 18 return accelerometer->Init() ? accelerometer.release() : NULL; |
19 } | 19 } |
20 | 20 |
21 AccelerometerMac::~AccelerometerMac() { | 21 AccelerometerMac::~AccelerometerMac() { |
22 } | 22 } |
23 | 23 |
24 AccelerometerMac::AccelerometerMac() { | 24 AccelerometerMac::AccelerometerMac() { |
25 } | 25 } |
26 | 26 |
| 27 const DeviceData* AccelerometerMac::GetDeviceData(DeviceData::Type type) { |
| 28 if (type != DeviceData::kTypeOrientation) |
| 29 return NULL; |
| 30 return GetOrientation(); |
| 31 } |
| 32 |
27 // Retrieve per-axis orientation values. | 33 // Retrieve per-axis orientation values. |
28 // | 34 // |
29 // Axes and angles are defined according to the W3C DeviceOrientation Draft. | 35 // Axes and angles are defined according to the W3C DeviceOrientation Draft. |
30 // See here: http://dev.w3.org/geo/api/spec-source-orientation.html | 36 // See here: http://dev.w3.org/geo/api/spec-source-orientation.html |
31 // | 37 // |
32 // Note: only beta and gamma angles are provided. Alpha is set to zero. | 38 // Note: only beta and gamma angles are provided. Alpha is set to zero. |
33 // | 39 // |
34 // Returns false in case of error. | 40 // Returns false in case of error. |
35 // | 41 // |
36 bool AccelerometerMac::GetOrientation(Orientation* orientation) { | 42 const Orientation* AccelerometerMac::GetOrientation() { |
37 DCHECK(sudden_motion_sensor_.get()); | 43 DCHECK(sudden_motion_sensor_.get()); |
38 | 44 |
39 // Retrieve per-axis calibrated values. | 45 // Retrieve per-axis calibrated values. |
40 float axis_value[3]; | 46 float axis_value[3]; |
41 if (!sudden_motion_sensor_->ReadSensorValues(axis_value)) | 47 if (!sudden_motion_sensor_->ReadSensorValues(axis_value)) |
42 return false; | 48 return NULL; |
43 | 49 |
44 // Transform the accelerometer values to W3C draft angles. | 50 // Transform the accelerometer values to W3C draft angles. |
45 // | 51 // |
46 // Accelerometer values are just dot products of the sensor axes | 52 // Accelerometer values are just dot products of the sensor axes |
47 // by the gravity vector 'g' with the result for the z axis inverted. | 53 // by the gravity vector 'g' with the result for the z axis inverted. |
48 // | 54 // |
49 // To understand this transformation calculate the 3rd row of the z-x-y | 55 // To understand this transformation calculate the 3rd row of the z-x-y |
50 // Euler angles rotation matrix (because of the 'g' vector, only 3rd row | 56 // Euler angles rotation matrix (because of the 'g' vector, only 3rd row |
51 // affects to the result). Note that z-x-y matrix means R = Ry * Rx * Rz. | 57 // affects to the result). Note that z-x-y matrix means R = Ry * Rx * Rz. |
52 // Then, assume alpha = 0 and you get this: | 58 // Then, assume alpha = 0 and you get this: |
53 // | 59 // |
54 // x_acc = sin(gamma) | 60 // x_acc = sin(gamma) |
55 // y_acc = - cos(gamma) * sin(beta) | 61 // y_acc = - cos(gamma) * sin(beta) |
56 // z_acc = cos(beta) * cos(gamma) | 62 // z_acc = cos(beta) * cos(gamma) |
57 // | 63 // |
58 // After that the rest is just a bit of trigonometry. | 64 // After that the rest is just a bit of trigonometry. |
59 // | 65 // |
60 // Also note that alpha can't be provided but it's assumed to be always zero. | 66 // Also note that alpha can't be provided but it's assumed to be always zero. |
61 // This is necessary in order to provide enough information to solve | 67 // This is necessary in order to provide enough information to solve |
62 // the equations. | 68 // the equations. |
63 // | 69 // |
64 const double kRad2deg = 180.0 / M_PI; | 70 const double kRad2deg = 180.0 / M_PI; |
65 | 71 |
| 72 scoped_refptr<Orientation> orientation(new Orientation()); |
| 73 |
66 orientation->set_beta(kRad2deg * atan2(-axis_value[1], axis_value[2])); | 74 orientation->set_beta(kRad2deg * atan2(-axis_value[1], axis_value[2])); |
67 orientation->set_gamma(kRad2deg * asin(axis_value[0])); | 75 orientation->set_gamma(kRad2deg * asin(axis_value[0])); |
68 // TODO(aousterh): should absolute_ be set to false here? | 76 // TODO(aousterh): should absolute_ be set to false here? |
69 // See crbug.com/136010. | 77 // See crbug.com/136010. |
70 | 78 |
71 // Make sure that the interval boundaries comply with the specification. At | 79 // Make sure that the interval boundaries comply with the specification. At |
72 // this point, beta is [-180, 180] and gamma is [-90, 90], but the spec has | 80 // this point, beta is [-180, 180] and gamma is [-90, 90], but the spec has |
73 // the upper bound open on both. | 81 // the upper bound open on both. |
74 if (orientation->beta() == 180.0) { | 82 if (orientation->beta() == 180.0) { |
75 orientation->set_beta(-180.0); // -180 == 180 (upside-down) | 83 orientation->set_beta(-180.0); // -180 == 180 (upside-down) |
76 } | 84 } |
77 if (orientation->gamma() == 90.0) { | 85 if (orientation->gamma() == 90.0) { |
78 static double just_less_than_90 = nextafter(90, 0); | 86 static double just_less_than_90 = nextafter(90, 0); |
79 orientation->set_gamma(just_less_than_90); | 87 orientation->set_gamma(just_less_than_90); |
80 } | 88 } |
81 | 89 |
82 // At this point, DCHECKing is paranoia. Never hurts. | 90 // At this point, DCHECKing is paranoia. Never hurts. |
83 DCHECK_GE(orientation->beta(), -180.0); | 91 DCHECK_GE(orientation->beta(), -180.0); |
84 DCHECK_LT(orientation->beta(), 180.0); | 92 DCHECK_LT(orientation->beta(), 180.0); |
85 DCHECK_GE(orientation->gamma(), -90.0); | 93 DCHECK_GE(orientation->gamma(), -90.0); |
86 DCHECK_LT(orientation->gamma(), 90.0); | 94 DCHECK_LT(orientation->gamma(), 90.0); |
87 | 95 |
88 return true; | 96 return orientation; |
89 } | 97 } |
90 | 98 |
91 bool AccelerometerMac::Init() { | 99 bool AccelerometerMac::Init() { |
92 sudden_motion_sensor_.reset(SuddenMotionSensor::Create()); | 100 sudden_motion_sensor_.reset(SuddenMotionSensor::Create()); |
93 return sudden_motion_sensor_.get() != NULL; | 101 return sudden_motion_sensor_.get() != NULL; |
94 } | 102 } |
95 | 103 |
96 } // namespace device_orientation | 104 } // namespace device_orientation |
OLD | NEW |