OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 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 "data_fetcher_shared_memory.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "third_party/sudden_motion_sensor/sudden_motion_sensor_mac.h" | |
9 | |
10 namespace { | |
11 | |
12 void FetchMotion(SuddenMotionSensor* sensor, | |
13 content::DeviceMotionHardwareBuffer* buffer) { | |
14 DCHECK(buffer); | |
15 | |
16 float axis_value[3]; | |
17 if (!sensor->ReadSensorValues(axis_value)) | |
18 return; | |
19 | |
20 buffer->seqlock.WriteBegin(); | |
21 buffer->data.accelerationIncludingGravityX = axis_value[0]; | |
22 buffer->data.hasAccelerationIncludingGravityX = true; | |
23 buffer->data.accelerationIncludingGravityY = axis_value[1]; | |
24 buffer->data.hasAccelerationIncludingGravityY = true; | |
25 buffer->data.accelerationIncludingGravityZ = axis_value[2]; | |
26 buffer->data.hasAccelerationIncludingGravityZ = true; | |
27 buffer->data.allAvailableSensorsAreActive = true; | |
28 buffer->seqlock.WriteEnd(); | |
29 } | |
30 | |
31 void FetchOrientation(SuddenMotionSensor* sensor, | |
32 content::DeviceOrientationHardwareBuffer* buffer) { | |
33 DCHECK(buffer); | |
34 | |
35 // Retrieve per-axis calibrated values. | |
36 float axis_value[3]; | |
37 if (!sensor->ReadSensorValues(axis_value)) | |
38 return; | |
39 | |
40 // Transform the accelerometer values to W3C draft angles. | |
41 // | |
42 // Accelerometer values are just dot products of the sensor axes | |
43 // by the gravity vector 'g' with the result for the z axis inverted. | |
44 // | |
45 // To understand this transformation calculate the 3rd row of the z-x-y | |
46 // Euler angles rotation matrix (because of the 'g' vector, only 3rd row | |
47 // affects to the result). Note that z-x-y matrix means R = Ry * Rx * Rz. | |
48 // Then, assume alpha = 0 and you get this: | |
49 // | |
50 // x_acc = sin(gamma) | |
51 // y_acc = - cos(gamma) * sin(beta) | |
52 // z_acc = cos(beta) * cos(gamma) | |
53 // | |
54 // After that the rest is just a bit of trigonometry. | |
55 // | |
56 // Also note that alpha can't be provided but it's assumed to be always zero. | |
57 // This is necessary in order to provide enough information to solve | |
58 // the equations. | |
59 // | |
60 const double kRad2deg = 180.0 / M_PI; | |
61 double beta = kRad2deg * atan2(-axis_value[1], axis_value[2]); | |
62 double gamma = kRad2deg * asin(axis_value[0]); | |
63 | |
64 // TODO(aousterh): should absolute_ be set to false here? | |
65 // See crbug.com/136010. | |
bulach
2013/08/23 16:03:34
is it still relevant?
timvolodine
2013/08/23 16:34:55
hmm yes, will need to figure that one out still..
| |
66 | |
67 // Make sure that the interval boundaries comply with the specification. At | |
68 // this point, beta is [-180, 180] and gamma is [-90, 90], but the spec has | |
69 // the upper bound open on both. | |
70 if (beta == 180.0) | |
71 beta = -180; // -180 == 180 (upside-down) | |
72 if (gamma == 90.0) | |
73 gamma = nextafter(90, 0); | |
74 | |
75 // At this point, DCHECKing is paranoia. Never hurts. | |
76 DCHECK_GE(beta, -180.0); | |
77 DCHECK_LT(beta, 180.0); | |
78 DCHECK_GE(gamma, -90.0); | |
79 DCHECK_LT(gamma, 90.0); | |
80 | |
81 buffer->seqlock.WriteBegin(); | |
82 buffer->data.beta = beta; | |
83 buffer->data.hasBeta = true; | |
84 buffer->data.gamma = gamma; | |
85 buffer->data.hasGamma = true; | |
86 buffer->data.allAvailableSensorsAreActive = true; | |
87 buffer->seqlock.WriteEnd(); | |
88 } | |
89 | |
90 } | |
bulach
2013/08/23 16:03:34
nit: // namespace
timvolodine
2013/08/23 16:34:55
Done.
| |
91 | |
92 namespace content { | |
93 | |
94 DataFetcherSharedMemory::DataFetcherSharedMemory() { | |
95 } | |
96 | |
97 DataFetcherSharedMemory::~DataFetcherSharedMemory() { | |
98 } | |
99 | |
100 void DataFetcherSharedMemory::Fetch(unsigned consumer_bitmask) { | |
101 DCHECK(base::MessageLoop::current() == GetPollingMessageLoop()); | |
102 DCHECK(sudden_motion_sensor_); | |
103 | |
104 if (consumer_bitmask & CONSUMER_TYPE_ORIENTATION) | |
105 FetchOrientation(sudden_motion_sensor_.get(), orientation_buffer_); | |
106 else if (consumer_bitmask & CONSUMER_TYPE_MOTION) | |
107 FetchMotion(sudden_motion_sensor_.get(), motion_buffer_); | |
108 | |
109 NOTREACHED(); | |
110 } | |
111 | |
112 bool DataFetcherSharedMemory::IsPolling() const { | |
113 return true; | |
114 } | |
115 | |
116 bool DataFetcherSharedMemory::Start(ConsumerType consumer_type) { | |
117 DCHECK(base::MessageLoop::current() == GetPollingMessageLoop()); | |
118 switch (consumer_type) { | |
119 case CONSUMER_TYPE_MOTION: | |
120 if (void* buffer = InitSharedMemoryBuffer(consumer_type, | |
121 sizeof(DeviceMotionHardwareBuffer))) { | |
122 motion_buffer_ = static_cast<DeviceMotionHardwareBuffer*>(buffer); | |
123 if (!sudden_motion_sensor_) | |
124 sudden_motion_sensor_.reset(SuddenMotionSensor::Create()); | |
125 return true; | |
126 } | |
127 case CONSUMER_TYPE_ORIENTATION: | |
128 if (void* buffer = InitSharedMemoryBuffer(consumer_type, | |
129 sizeof(DeviceOrientationHardwareBuffer))) { | |
130 orientation_buffer_ = | |
131 static_cast<DeviceOrientationHardwareBuffer*>(buffer); | |
132 if (!sudden_motion_sensor_) | |
133 sudden_motion_sensor_.reset(SuddenMotionSensor::Create()); | |
134 return true; | |
135 } | |
136 default: | |
137 NOTREACHED(); | |
138 } | |
139 return false; | |
140 } | |
141 | |
142 bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) { | |
143 DCHECK(base::MessageLoop::current() == GetPollingMessageLoop()); | |
144 switch (consumer_type) { | |
145 case CONSUMER_TYPE_MOTION: | |
146 motion_buffer_->seqlock.WriteBegin(); | |
147 motion_buffer_->data.allAvailableSensorsAreActive = false; | |
148 motion_buffer_->seqlock.WriteEnd(); | |
149 motion_buffer_ = NULL; | |
150 return true; | |
151 case CONSUMER_TYPE_ORIENTATION: | |
152 orientation_buffer_->seqlock.WriteBegin(); | |
153 orientation_buffer_->data.allAvailableSensorsAreActive = false; | |
154 orientation_buffer_->seqlock.WriteEnd(); | |
155 orientation_buffer_ = NULL; | |
156 return true; | |
157 default: | |
158 NOTREACHED(); | |
159 } | |
160 return false; | |
161 } | |
162 | |
163 } // namespace content | |
OLD | NEW |