Commit cf13abba authored by Alexander Shalamov's avatar Alexander Shalamov Committed by Commit Bot

[sensors][win] Reverse axis signs for motion sensors

This CL reverses axis signs for gyroscope, magnetometer and absolute
orientation sensors. Before the change, wrong coordinate system was
used based on the accelerometer's data. Integrating Motion and Orientation
Sensors [1] document, explains what coordinate system must be used and why
accelerometer's measurements differ from other platforms.

[1] https://msdn.microsoft.com/en-us/library/windows/hardware/dn642102(v=vs.85).aspx

Bug: 786252
Change-Id: I4afbc1a1d5fb03c3e2e0538a8ea7424c40020eca
Reviewed-on: https://chromium-review.googlesource.com/804624Reviewed-by: default avatarMikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarJun Cai <juncai@chromium.org>
Commit-Queue: Alexander Shalamov <alexander.shalamov@intel.com>
Cr-Commit-Position: refs/heads/master@{#522380}
parent 1ab2b596
...@@ -599,9 +599,9 @@ TEST_F(PlatformSensorAndProviderTestWin, CheckGyroscopeReadingConversion) { ...@@ -599,9 +599,9 @@ TEST_F(PlatformSensorAndProviderTestWin, CheckGyroscopeReadingConversion) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
SensorReadingSharedBuffer* buffer = SensorReadingSharedBuffer* buffer =
static_cast<SensorReadingSharedBuffer*>(mapping.get()); static_cast<SensorReadingSharedBuffer*>(mapping.get());
EXPECT_THAT(buffer->reading.gyro.x, gfx::DegToRad(-x_ang_accel)); EXPECT_THAT(buffer->reading.gyro.x, gfx::DegToRad(x_ang_accel));
EXPECT_THAT(buffer->reading.gyro.y, gfx::DegToRad(-y_ang_accel)); EXPECT_THAT(buffer->reading.gyro.y, gfx::DegToRad(y_ang_accel));
EXPECT_THAT(buffer->reading.gyro.z, gfx::DegToRad(-z_ang_accel)); EXPECT_THAT(buffer->reading.gyro.z, gfx::DegToRad(z_ang_accel));
EXPECT_TRUE(sensor->StopListening(client.get(), configuration)); EXPECT_TRUE(sensor->StopListening(client.get(), configuration));
} }
...@@ -639,9 +639,9 @@ TEST_F(PlatformSensorAndProviderTestWin, CheckMagnetometerReadingConversion) { ...@@ -639,9 +639,9 @@ TEST_F(PlatformSensorAndProviderTestWin, CheckMagnetometerReadingConversion) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
SensorReadingSharedBuffer* buffer = SensorReadingSharedBuffer* buffer =
static_cast<SensorReadingSharedBuffer*>(mapping.get()); static_cast<SensorReadingSharedBuffer*>(mapping.get());
EXPECT_THAT(buffer->reading.magn.x, -x_magn_field * kMicroteslaInMilligauss); EXPECT_THAT(buffer->reading.magn.x, x_magn_field * kMicroteslaInMilligauss);
EXPECT_THAT(buffer->reading.magn.y, -y_magn_field * kMicroteslaInMilligauss); EXPECT_THAT(buffer->reading.magn.y, y_magn_field * kMicroteslaInMilligauss);
EXPECT_THAT(buffer->reading.magn.z, -z_magn_field * kMicroteslaInMilligauss); EXPECT_THAT(buffer->reading.magn.z, z_magn_field * kMicroteslaInMilligauss);
EXPECT_TRUE(sensor->StopListening(client.get(), configuration)); EXPECT_TRUE(sensor->StopListening(client.get(), configuration));
} }
...@@ -730,9 +730,9 @@ TEST_F(PlatformSensorAndProviderTestWin, ...@@ -730,9 +730,9 @@ TEST_F(PlatformSensorAndProviderTestWin,
SensorReadingSharedBuffer* buffer = SensorReadingSharedBuffer* buffer =
static_cast<SensorReadingSharedBuffer*>(mapping.get()); static_cast<SensorReadingSharedBuffer*>(mapping.get());
EXPECT_THAT(buffer->reading.orientation_quat.x, -x); EXPECT_THAT(buffer->reading.orientation_quat.x, x);
EXPECT_THAT(buffer->reading.orientation_quat.y, -y); EXPECT_THAT(buffer->reading.orientation_quat.y, y);
EXPECT_THAT(buffer->reading.orientation_quat.z, -z); EXPECT_THAT(buffer->reading.orientation_quat.z, z);
EXPECT_THAT(buffer->reading.orientation_quat.w, w); EXPECT_THAT(buffer->reading.orientation_quat.w, w);
EXPECT_TRUE(sensor->StopListening(client.get(), configuration)); EXPECT_TRUE(sensor->StopListening(client.get(), configuration));
} }
......
...@@ -88,9 +88,15 @@ std::unique_ptr<ReaderInitParams> CreateAccelerometerReaderInitParams() { ...@@ -88,9 +88,15 @@ std::unique_ptr<ReaderInitParams> CreateAccelerometerReaderInitParams() {
return E_FAIL; return E_FAIL;
} }
// Windows uses coordinate system where Z axis points down from device // Windows HW sensor integration requirements specify accelerometer
// screen, therefore, using right hand notation, we have to reverse // measurements conventions such as, the accelerometer sensor must expose
// sign for each axis. Values are converted from G/s^2 to m/s^2. // values that are proportional and in the same direction as the force of
// gravity. Therefore, sensor hosted by the device at rest on a leveled
// surface while the screen is facing towards the sky, must report -1G along
// the Z axis.
// https://msdn.microsoft.com/en-us/library/windows/hardware/dn642102(v=vs.85).aspx
// Change sign of values, to report 'reaction force', and convert values
// from G/s^2 to m/s^2 units.
reading->accel.x = -x * kMeanGravity; reading->accel.x = -x * kMeanGravity;
reading->accel.y = -y * kMeanGravity; reading->accel.y = -y * kMeanGravity;
reading->accel.z = -z * kMeanGravity; reading->accel.z = -z * kMeanGravity;
...@@ -119,12 +125,10 @@ std::unique_ptr<ReaderInitParams> CreateGyroscopeReaderInitParams() { ...@@ -119,12 +125,10 @@ std::unique_ptr<ReaderInitParams> CreateGyroscopeReaderInitParams() {
return E_FAIL; return E_FAIL;
} }
// Windows uses coordinate system where Z axis points down from device // Values are converted from degrees to radians.
// screen, therefore, using right hand notation, we have to reverse reading->gyro.x = gfx::DegToRad(x);
// sign for each axis. Values are converted from deg to rad. reading->gyro.y = gfx::DegToRad(y);
reading->gyro.x = gfx::DegToRad(-x); reading->gyro.z = gfx::DegToRad(z);
reading->gyro.y = gfx::DegToRad(-y);
reading->gyro.z = gfx::DegToRad(-z);
return S_OK; return S_OK;
}; };
return params; return params;
...@@ -150,13 +154,10 @@ std::unique_ptr<ReaderInitParams> CreateMagnetometerReaderInitParams() { ...@@ -150,13 +154,10 @@ std::unique_ptr<ReaderInitParams> CreateMagnetometerReaderInitParams() {
return E_FAIL; return E_FAIL;
} }
// Windows uses coordinate system where Z axis points down from device // Values are converted from Milligaus to Microtesla.
// screen, therefore, using right hand notation, we have to reverse reading->magn.x = x * kMicroteslaInMilligauss;
// sign for each axis. Values are converted from Milligaus to reading->magn.y = y * kMicroteslaInMilligauss;
// Microtesla. reading->magn.z = z * kMicroteslaInMilligauss;
reading->magn.x = -x * kMicroteslaInMilligauss;
reading->magn.y = -y * kMicroteslaInMilligauss;
reading->magn.z = -z * kMicroteslaInMilligauss;
return S_OK; return S_OK;
}; };
return params; return params;
...@@ -204,12 +205,9 @@ CreateAbsoluteOrientationQuaternionReaderInitParams() { ...@@ -204,12 +205,9 @@ CreateAbsoluteOrientationQuaternionReaderInitParams() {
float* quat = reinterpret_cast<float*>(quat_variant.get().caub.pElems); float* quat = reinterpret_cast<float*>(quat_variant.get().caub.pElems);
// Windows uses coordinate system where Z axis points down from device reading->orientation_quat.x = quat[0]; // x*sin(Theta/2)
// screen, therefore, using right hand notation, we have to reverse reading->orientation_quat.y = quat[1]; // y*sin(Theta/2)
// sign for each quaternion component. reading->orientation_quat.z = quat[2]; // z*sin(Theta/2)
reading->orientation_quat.x = -quat[0]; // x*sin(Theta/2)
reading->orientation_quat.y = -quat[1]; // y*sin(Theta/2)
reading->orientation_quat.z = -quat[2]; // z*sin(Theta/2)
reading->orientation_quat.w = quat[3]; // cos(Theta/2) reading->orientation_quat.w = quat[3]; // cos(Theta/2)
return S_OK; return S_OK;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment