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

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: 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
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 SuddenMotionSensor::kGenericSenso r = {
Leandro Graciá Gil 2012/03/28 14:22:44 More than 80 chars.
hans 2012/03/28 14:57:55 Done.
105 AccelerometerMac::kGenericSensor = {
106 "SMCMotionSensor", 2, 102 "SMCMotionSensor", 2,
107 0, 251, 103 0, 251,
108 5, 40 104 5, 40
109 }; 105 };
110 106
111 // Supported sensor descriptors. Add entries here to enhance compatibility. 107 // Supported sensor descriptors. Add entries here to enhance compatibility.
112 // Tested in order; place more specific entries before more general ones. (All 108 // Tested in order; place more specific entries before more general ones. (All
113 // non-tested entries from SMSLib have been removed.) 109 // non-tested entries from SMSLib have been removed.)
114 const AccelerometerMac::SensorDescriptor 110 const SuddenMotionSensor::SensorDescriptor
115 AccelerometerMac::kSupportedSensors[] = { 111 SuddenMotionSensor::kSupportedSensors[] = {
116 // Tested by tommyw on a 13" MacBook. 112 // Tested by tommyw on a 13" MacBook.
117 { "MacBook1,1", NULL, { { 0, true }, { 2, true }, { 4, false } } }, 113 { "MacBook1,1", NULL, { { 0, true }, { 2, true }, { 4, false } } },
118 114
119 // Tested by S.Selz. (via avi) on a 13" MacBook. 115 // Tested by S.Selz. (via avi) on a 13" MacBook.
120 { "MacBook2,1", NULL, { { 0, true }, { 2, false }, { 4, true } } }, 116 { "MacBook2,1", NULL, { { 0, true }, { 2, false }, { 4, true } } },
121 117
122 // Tested by verhees on a 13" MacBook. 118 // Tested by verhees on a 13" MacBook.
123 { "MacBook3,1", NULL, { { 0, true }, { 2, true }, { 4, false } } }, 119 { "MacBook3,1", NULL, { { 0, true }, { 2, true }, { 4, false } } },
124 120
125 // Tested by adlr on a 13" MacBook. 121 // Tested by adlr on a 13" MacBook.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 201
206 // Tested by avi on a 17" MacBook Pro. 202 // Tested by avi on a 17" MacBook Pro.
207 { "MacBookPro8,3", NULL, { { 0, false }, { 2, false }, { 4, false } } }, 203 { "MacBookPro8,3", NULL, { { 0, false }, { 2, false }, { 4, false } } },
208 204
209 // Generic MacBook accelerometer sensor data, to be used for future models 205 // 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 206 // until they can be tested and their data entered. Note that this generic
211 // configuration may well have problems with inverted axes. 207 // configuration may well have problems with inverted axes.
212 { "", NULL, { { 0, true }, { 2, true }, { 4, false } } } 208 { "", NULL, { { 0, true }, { 2, true }, { 4, false } } }
213 }; 209 };
214 210
215 // Create a AccelerometerMac object and return NULL if no valid sensor found. 211 // Create a SuddenMotionSensor object and return NULL if no valid sensor found.
216 DataFetcher* AccelerometerMac::Create() { 212 SuddenMotionSensor* SuddenMotionSensor::Create() {
217 scoped_ptr<AccelerometerMac> accelerometer(new AccelerometerMac); 213 scoped_ptr<SuddenMotionSensor> accelerometer(new SuddenMotionSensor);
218 return accelerometer->Init() ? accelerometer.release() : NULL; 214 return accelerometer->Init() ? accelerometer.release() : NULL;
219 } 215 }
220 216
221 AccelerometerMac::~AccelerometerMac() { 217 SuddenMotionSensor::~SuddenMotionSensor() {
222 IOServiceClose(io_connection_); 218 IOServiceClose(io_connection_);
223 } 219 }
224 220
225 AccelerometerMac::AccelerometerMac() 221 SuddenMotionSensor::SuddenMotionSensor()
226 : sensor_(NULL), 222 : sensor_(NULL),
227 io_connection_(0) { 223 io_connection_(0) {
228 } 224 }
229 225
230 // Retrieve per-axis accelerometer values. 226 // Retrieve per-axis accelerometer values.
231 // 227 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_); 228 DCHECK(sensor_);
241 229
242 // Reset output record memory buffer. 230 // Reset output record memory buffer.
243 std::fill(output_record_.begin(), output_record_.end(), 0x00); 231 std::fill(output_record_.begin(), output_record_.end(), 0x00);
244 232
245 // Read record data from memory. 233 // Read record data from memory.
246 const size_t kInputSize = kGenericSensor.record_size; 234 const size_t kInputSize = kGenericSensor.record_size;
247 size_t output_size = kGenericSensor.record_size; 235 size_t output_size = kGenericSensor.record_size;
248 236
249 if (IOConnectCallStructMethod(io_connection_, kGenericSensor.function, 237 if (IOConnectCallStructMethod(io_connection_, kGenericSensor.function,
(...skipping 28 matching lines...) Expand all
278 if (axis_value[i] < -1.0) 266 if (axis_value[i] < -1.0)
279 axis_value[i] = -1.0; 267 axis_value[i] = -1.0;
280 else if (axis_value[i] > 1.0) 268 else if (axis_value[i] > 1.0)
281 axis_value[i] = 1.0; 269 axis_value[i] = 1.0;
282 270
283 // Apply axis inversion. 271 // Apply axis inversion.
284 if (sensor_->axis[i].inverted) 272 if (sensor_->axis[i].inverted)
285 axis_value[i] = -axis_value[i]; 273 axis_value[i] = -axis_value[i];
286 } 274 }
287 275
288 // Transform the accelerometer values to W3C draft angles. 276 axes[0] = axis_value[0];
289 // 277 axes[1] = axis_value[1];
290 // Accelerometer values are just dot products of the sensor axes 278 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 279
337 return true; 280 return true;
338 } 281 }
339 282
340 // Probe the local hardware looking for a supported sensor device 283 // Probe the local hardware looking for a supported sensor device
341 // and initialize an I/O connection to it. 284 // and initialize an I/O connection to it.
342 bool AccelerometerMac::Init() { 285 bool SuddenMotionSensor::Init() {
343 // Request model name from the kernel. 286 // Request model name from the kernel.
344 char local_model[32]; // size from SMSLib 287 char local_model[32]; // size from SMSLib
345 size_t local_model_size = sizeof(local_model); 288 size_t local_model_size = sizeof(local_model);
346 int params[2] = { CTL_HW, HW_MODEL }; 289 int params[2] = { CTL_HW, HW_MODEL };
347 if (sysctl(params, 2, local_model, &local_model_size, NULL, 0) != 0) 290 if (sysctl(params, 2, local_model, &local_model_size, NULL, 0) != 0)
348 return NULL; 291 return NULL;
349 292
350 const SensorDescriptor* sensor_candidate = NULL; 293 const SensorDescriptor* sensor_candidate = NULL;
351 294
352 // Look for the current model in the supported sensor list. 295 // Look for the current model in the supported sensor list.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 } 362 }
420 363
421 if (sensor_ == NULL) 364 if (sensor_ == NULL)
422 return false; 365 return false;
423 366
424 // Allocate and initialize input/output records. 367 // Allocate and initialize input/output records.
425 input_record_.resize(kGenericSensor.record_size, 0x01); 368 input_record_.resize(kGenericSensor.record_size, 0x01);
426 output_record_.resize(kGenericSensor.record_size, 0x00); 369 output_record_.resize(kGenericSensor.record_size, 0x00);
427 370
428 // Try to retrieve the current orientation. 371 // Try to retrieve the current orientation.
429 Orientation test_orientation; 372 float test_axes[3];
430 return GetOrientation(&test_orientation); 373 return ReadSensorValues(test_axes);
431 } 374 }
432 375
433 // Extend the sign of an integer of less than 32 bits to a 32-bit integer. 376 // 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) { 377 int SuddenMotionSensor::ExtendSign(int value, size_t size) {
435 switch (size) { 378 switch (size) {
436 case 1: 379 case 1:
437 if (value & 0x00000080) 380 if (value & 0x00000080)
438 return value | 0xffffff00; 381 return value | 0xffffff00;
439 break; 382 break;
440 383
441 case 2: 384 case 2:
442 if (value & 0x00008000) 385 if (value & 0x00008000)
443 return value | 0xffff0000; 386 return value | 0xffff0000;
444 break; 387 break;
445 388
446 case 3: 389 case 3:
447 if (value & 0x00800000) 390 if (value & 0x00800000)
448 return value | 0xff000000; 391 return value | 0xff000000;
449 break; 392 break;
450 393
451 default: 394 default:
452 LOG(FATAL) << "Invalid integer size for sign extension: " << size; 395 LOG(FATAL) << "Invalid integer size for sign extension: " << size;
453 } 396 }
454 397
455 return value; 398 return value;
456 } 399 }
457
458 } // namespace device_orientation
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698