Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: third_party/sudden_motion_sensor/sudden_motion_sensor_mac.cc

Issue 9844020: Move the Sudden Motion Sensor library into third_party. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: DEPS: convert line endings Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/sudden_motion_sensor/sudden_motion_sensor_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // This file is based on the SMSLib library. 5 // This file is based on the SMSLib library.
6 // 6 //
7 // SMSLib Sudden Motion Sensor Access Library 7 // SMSLib Sudden Motion Sensor Access Library
8 // Copyright (c) 2010 Suitable Systems 8 // Copyright (c) 2010 Suitable Systems
9 // All rights reserved. 9 // All rights reserved.
10 // 10 //
(...skipping 30 matching lines...) Expand all
41 // 41 //
42 // For more information about SMSLib, see 42 // For more information about SMSLib, see
43 // <http://www.suitable.com/tools/smslib.html> 43 // <http://www.suitable.com/tools/smslib.html>
44 // or contact 44 // or contact
45 // Daniel Griscom 45 // Daniel Griscom
46 // Suitable Systems 46 // Suitable Systems
47 // 1 Centre Street, Suite 204 47 // 1 Centre Street, Suite 204
48 // Wakefield, MA 01880 48 // Wakefield, MA 01880
49 // (781) 665-0053 49 // (781) 665-0053
50 50
51 #include "content/browser/device_orientation/accelerometer_mac.h" 51 #include "sudden_motion_sensor_mac.h"
52 52
53 #include <math.h> 53 #include <math.h>
54 #include <sys/sysctl.h> 54 #include <sys/sysctl.h>
55 55
56 #include "base/logging.h" 56 #include "base/logging.h"
57 #include "base/mac/scoped_cftyperef.h" 57 #include "base/mac/scoped_cftyperef.h"
58 #include "base/memory/scoped_ptr.h" 58 #include "base/memory/scoped_ptr.h"
59 #include "content/browser/device_orientation/orientation.h"
60 59
61 namespace device_orientation { 60 struct SuddenMotionSensor::GenericMacbookSensor {
62
63 struct AccelerometerMac::GenericMacbookSensor {
64 // Name of device to be read. 61 // Name of device to be read.
65 const char* service_name; 62 const char* service_name;
66 63
67 // Number of bytes of the axis data. 64 // Number of bytes of the axis data.
68 int axis_size; 65 int axis_size;
69 66
70 // Default calibration value for zero g. 67 // Default calibration value for zero g.
71 float zero_g; 68 float zero_g;
72 69
73 // Default calibration value for one g (negative when axis is inverted). 70 // Default calibration value for one g (negative when axis is inverted).
74 float one_g; 71 float one_g;
75 72
76 // Kernel function index. 73 // Kernel function index.
77 unsigned int function; 74 unsigned int function;
78 75
79 // Size of the sensor record to be sent/received. 76 // Size of the sensor record to be sent/received.
80 unsigned int record_size; 77 unsigned int record_size;
81 }; 78 };
82 79
83 struct AccelerometerMac::AxisData { 80 struct SuddenMotionSensor::AxisData {
84 // Location of the first byte representing the axis in the sensor data. 81 // Location of the first byte representing the axis in the sensor data.
85 int index; 82 int index;
86 83
87 // Axis inversion flag. The value changes often between models. 84 // Axis inversion flag. The value changes often between models.
88 bool inverted; 85 bool inverted;
89 }; 86 };
90 87
91 // Sudden Motion Sensor descriptor. 88 // Sudden Motion Sensor descriptor.
92 struct AccelerometerMac::SensorDescriptor { 89 struct SuddenMotionSensor::SensorDescriptor {
93 // Prefix of model to be tested. 90 // Prefix of model to be tested.
94 const char* model_name; 91 const char* model_name;
95 92
96 // Board id of model, or NULL if it doesn't matter. 93 // Board id of model, or NULL if it doesn't matter.
97 const char* board_id; 94 const char* board_id;
98 95
99 // Axis-specific data (x,y,z order). 96 // Axis-specific data (x,y,z order).
100 AxisData axis[3]; 97 AxisData axis[3];
101 }; 98 };
102 99
103 // Typical sensor parameters in MacBook models. 100 // Typical sensor parameters in MacBook models.
104 const AccelerometerMac::GenericMacbookSensor 101 const SuddenMotionSensor::GenericMacbookSensor
105 AccelerometerMac::kGenericSensor = { 102 SuddenMotionSensor::kGenericSensor = {
106 "SMCMotionSensor", 2, 103 "SMCMotionSensor", 2,
107 0, 251, 104 0, 251,
108 5, 40 105 5, 40
109 }; 106 };
110 107
111 // Supported sensor descriptors. Add entries here to enhance compatibility. 108 // Supported sensor descriptors. Add entries here to enhance compatibility.
112 // Tested in order; place more specific entries before more general ones. (All 109 // Tested in order; place more specific entries before more general ones. (All
113 // non-tested entries from SMSLib have been removed.) 110 // non-tested entries from SMSLib have been removed.)
114 const AccelerometerMac::SensorDescriptor 111 const SuddenMotionSensor::SensorDescriptor
115 AccelerometerMac::kSupportedSensors[] = { 112 SuddenMotionSensor::kSupportedSensors[] = {
116 // Tested by tommyw on a 13" MacBook. 113 // Tested by tommyw on a 13" MacBook.
117 { "MacBook1,1", NULL, { { 0, true }, { 2, true }, { 4, false } } }, 114 { "MacBook1,1", NULL, { { 0, true }, { 2, true }, { 4, false } } },
118 115
119 // Tested by S.Selz. (via avi) on a 13" MacBook. 116 // Tested by S.Selz. (via avi) on a 13" MacBook.
120 { "MacBook2,1", NULL, { { 0, true }, { 2, false }, { 4, true } } }, 117 { "MacBook2,1", NULL, { { 0, true }, { 2, false }, { 4, true } } },
121 118
122 // Tested by verhees on a 13" MacBook. 119 // Tested by verhees on a 13" MacBook.
123 { "MacBook3,1", NULL, { { 0, true }, { 2, true }, { 4, false } } }, 120 { "MacBook3,1", NULL, { { 0, true }, { 2, true }, { 4, false } } },
124 121
125 // Tested by adlr on a 13" MacBook. 122 // Tested by adlr on a 13" MacBook.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 202
206 // Tested by avi on a 17" MacBook Pro. 203 // Tested by avi on a 17" MacBook Pro.
207 { "MacBookPro8,3", NULL, { { 0, false }, { 2, false }, { 4, false } } }, 204 { "MacBookPro8,3", NULL, { { 0, false }, { 2, false }, { 4, false } } },
208 205
209 // Generic MacBook accelerometer sensor data, to be used for future models 206 // Generic MacBook accelerometer sensor data, to be used for future models
210 // until they can be tested and their data entered. Note that this generic 207 // until they can be tested and their data entered. Note that this generic
211 // configuration may well have problems with inverted axes. 208 // configuration may well have problems with inverted axes.
212 { "", NULL, { { 0, true }, { 2, true }, { 4, false } } } 209 { "", NULL, { { 0, true }, { 2, true }, { 4, false } } }
213 }; 210 };
214 211
215 // Create a AccelerometerMac object and return NULL if no valid sensor found. 212 // Create a SuddenMotionSensor object and return NULL if no valid sensor found.
216 DataFetcher* AccelerometerMac::Create() { 213 SuddenMotionSensor* SuddenMotionSensor::Create() {
217 scoped_ptr<AccelerometerMac> accelerometer(new AccelerometerMac); 214 scoped_ptr<SuddenMotionSensor> accelerometer(new SuddenMotionSensor);
218 return accelerometer->Init() ? accelerometer.release() : NULL; 215 return accelerometer->Init() ? accelerometer.release() : NULL;
219 } 216 }
220 217
221 AccelerometerMac::~AccelerometerMac() { 218 SuddenMotionSensor::~SuddenMotionSensor() {
222 IOServiceClose(io_connection_); 219 IOServiceClose(io_connection_);
223 } 220 }
224 221
225 AccelerometerMac::AccelerometerMac() 222 SuddenMotionSensor::SuddenMotionSensor()
226 : sensor_(NULL), 223 : sensor_(NULL),
227 io_connection_(0) { 224 io_connection_(0) {
228 } 225 }
229 226
230 // Retrieve per-axis accelerometer values. 227 // Retrieve per-axis accelerometer values.
231 // 228 bool SuddenMotionSensor::ReadSensorValues(float axes[3]) {
232 // Axes and angles are defined according to the W3C DeviceOrientation Draft.
233 // See here: http://dev.w3.org/geo/api/spec-source-orientation.html
234 //
235 // Note: only beta and gamma angles are provided. Alpha is set to zero.
236 //
237 // Returns false in case of error or non-properly initialized object.
238 //
239 bool AccelerometerMac::GetOrientation(Orientation* orientation) {
240 DCHECK(sensor_); 229 DCHECK(sensor_);
241 230
242 // Reset output record memory buffer. 231 // Reset output record memory buffer.
243 std::fill(output_record_.begin(), output_record_.end(), 0x00); 232 std::fill(output_record_.begin(), output_record_.end(), 0x00);
244 233
245 // Read record data from memory. 234 // Read record data from memory.
246 const size_t kInputSize = kGenericSensor.record_size; 235 const size_t kInputSize = kGenericSensor.record_size;
247 size_t output_size = kGenericSensor.record_size; 236 size_t output_size = kGenericSensor.record_size;
248 237
249 if (IOConnectCallStructMethod(io_connection_, kGenericSensor.function, 238 if (IOConnectCallStructMethod(io_connection_, kGenericSensor.function,
(...skipping 28 matching lines...) Expand all
278 if (axis_value[i] < -1.0) 267 if (axis_value[i] < -1.0)
279 axis_value[i] = -1.0; 268 axis_value[i] = -1.0;
280 else if (axis_value[i] > 1.0) 269 else if (axis_value[i] > 1.0)
281 axis_value[i] = 1.0; 270 axis_value[i] = 1.0;
282 271
283 // Apply axis inversion. 272 // Apply axis inversion.
284 if (sensor_->axis[i].inverted) 273 if (sensor_->axis[i].inverted)
285 axis_value[i] = -axis_value[i]; 274 axis_value[i] = -axis_value[i];
286 } 275 }
287 276
288 // Transform the accelerometer values to W3C draft angles. 277 axes[0] = axis_value[0];
289 // 278 axes[1] = axis_value[1];
290 // Accelerometer values are just dot products of the sensor axes 279 axes[2] = axis_value[2];
291 // by the gravity vector 'g' with the result for the z axis inverted.
292 //
293 // To understand this transformation calculate the 3rd row of the z-x-y
294 // Euler angles rotation matrix (because of the 'g' vector, only 3rd row
295 // affects to the result). Note that z-x-y matrix means R = Ry * Rx * Rz.
296 // Then, assume alpha = 0 and you get this:
297 //
298 // x_acc = sin(gamma)
299 // y_acc = - cos(gamma) * sin(beta)
300 // z_acc = cos(beta) * cos(gamma)
301 //
302 // After that the rest is just a bit of trigonometry.
303 //
304 // Also note that alpha can't be provided but it's assumed to be always zero.
305 // This is necessary in order to provide enough information to solve
306 // the equations.
307 //
308 const double kRad2deg = 180.0 / M_PI;
309
310 orientation->alpha_ = 0.0;
311 orientation->beta_ = kRad2deg * atan2(-axis_value[1], axis_value[2]);
312 orientation->gamma_ = kRad2deg * asin(axis_value[0]);
313 orientation->absolute_ = false;
314
315 // Make sure that the interval boundaries comply with the specification. At
316 // this point, beta is [-180, 180] and gamma is [-90, 90], but the spec has
317 // the upper bound open on both.
318 if (orientation->beta_ == 180.0) {
319 orientation->beta_ = -180.0; // -180 == 180 (upside-down)
320 }
321 if (orientation->gamma_ == 90.0) {
322 static double just_less_than_90 = nextafter(90, 0);
323 orientation->gamma_ = just_less_than_90;
324 }
325
326 // At this point, DCHECKing is paranoia. Never hurts.
327 DCHECK_GE(orientation->beta_, -180.0);
328 DCHECK_LT(orientation->beta_, 180.0);
329 DCHECK_GE(orientation->gamma_, -90.0);
330 DCHECK_LT(orientation->gamma_, 90.0);
331
332 orientation->can_provide_alpha_ = false;
333 orientation->can_provide_beta_ = true;
334 orientation->can_provide_gamma_ = true;
335 orientation->can_provide_absolute_ = false;
336 280
337 return true; 281 return true;
338 } 282 }
339 283
340 // Probe the local hardware looking for a supported sensor device 284 // Probe the local hardware looking for a supported sensor device
341 // and initialize an I/O connection to it. 285 // and initialize an I/O connection to it.
342 bool AccelerometerMac::Init() { 286 bool SuddenMotionSensor::Init() {
343 // Request model name from the kernel. 287 // Request model name from the kernel.
344 char local_model[32]; // size from SMSLib 288 char local_model[32]; // size from SMSLib
345 size_t local_model_size = sizeof(local_model); 289 size_t local_model_size = sizeof(local_model);
346 int params[2] = { CTL_HW, HW_MODEL }; 290 int params[2] = { CTL_HW, HW_MODEL };
347 if (sysctl(params, 2, local_model, &local_model_size, NULL, 0) != 0) 291 if (sysctl(params, 2, local_model, &local_model_size, NULL, 0) != 0)
348 return NULL; 292 return NULL;
349 293
350 const SensorDescriptor* sensor_candidate = NULL; 294 const SensorDescriptor* sensor_candidate = NULL;
351 295
352 // Look for the current model in the supported sensor list. 296 // Look for the current model in the supported sensor list.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 } 363 }
420 364
421 if (sensor_ == NULL) 365 if (sensor_ == NULL)
422 return false; 366 return false;
423 367
424 // Allocate and initialize input/output records. 368 // Allocate and initialize input/output records.
425 input_record_.resize(kGenericSensor.record_size, 0x01); 369 input_record_.resize(kGenericSensor.record_size, 0x01);
426 output_record_.resize(kGenericSensor.record_size, 0x00); 370 output_record_.resize(kGenericSensor.record_size, 0x00);
427 371
428 // Try to retrieve the current orientation. 372 // Try to retrieve the current orientation.
429 Orientation test_orientation; 373 float test_axes[3];
430 return GetOrientation(&test_orientation); 374 return ReadSensorValues(test_axes);
431 } 375 }
432 376
433 // Extend the sign of an integer of less than 32 bits to a 32-bit integer. 377 // Extend the sign of an integer of less than 32 bits to a 32-bit integer.
434 int AccelerometerMac::ExtendSign(int value, size_t size) { 378 int SuddenMotionSensor::ExtendSign(int value, size_t size) {
435 switch (size) { 379 switch (size) {
436 case 1: 380 case 1:
437 if (value & 0x00000080) 381 if (value & 0x00000080)
438 return value | 0xffffff00; 382 return value | 0xffffff00;
439 break; 383 break;
440 384
441 case 2: 385 case 2:
442 if (value & 0x00008000) 386 if (value & 0x00008000)
443 return value | 0xffff0000; 387 return value | 0xffff0000;
444 break; 388 break;
445 389
446 case 3: 390 case 3:
447 if (value & 0x00800000) 391 if (value & 0x00800000)
448 return value | 0xff000000; 392 return value | 0xff000000;
449 break; 393 break;
450 394
451 default: 395 default:
452 LOG(FATAL) << "Invalid integer size for sign extension: " << size; 396 LOG(FATAL) << "Invalid integer size for sign extension: " << size;
453 } 397 }
454 398
455 return value; 399 return value;
456 } 400 }
457
458 } // namespace device_orientation
OLDNEW
« no previous file with comments | « third_party/sudden_motion_sensor/sudden_motion_sensor_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698