2#include "orientationTracker.h"
3#include "tools/SO3Util.h"
6static const float defaultNeckHorizontalOffset = 0.08f;
7static const float defaultNeckVerticalOffset = 0.075f;
9OrientationTracker::OrientationTracker() :
10 mDisplayFromDevice(
Quaternion(1.0f, 0.0f, 0.0f, 0.0f)),
11 mInertialReferenceFrameFromWorld(
Quaternion(sqrt(0.5f), -sqrt(0.5f), 0.0f, 0.0f)),
12 mLastGyroEventTimestamp(0),
13 mOrientationCorrectionAngle(0),
14 mNeckModelEnabled(true)
16 mNeckModelTranslation = Matrix4::IDENTITY;
18 translationMatrix.makeTrans(0.0f, - defaultNeckVerticalOffset, defaultNeckHorizontalOffset);
19 mNeckModelTranslation = mNeckModelTranslation * translationMatrix;
22OrientationTracker::~OrientationTracker()
26void OrientationTracker::startTracking(DeviceOrientation orientation)
28 updateDeviceOrientation(orientation);
29 mBiasEstimator.reset();
33void OrientationTracker::processGyro(
Vector3d gyro, int64_t sensorTimeStamp)
36 mLastGyroEventTimestamp = GetTickCountNano();
37 mBiasEstimator.processGyroscope(gyro, sensorTimeStamp);
38 mBiasEstimator.getGyroBias(mGyroBias);
40 Vector3d::sub(gyro, mGyroBias, gyro);
41 mTracker.processGyro(gyro, sensorTimeStamp);
44void OrientationTracker::processAcceleration(
Vector3d acc, int64_t sensorTimeStamp)
46 mTracker.processAcc(acc, sensorTimeStamp);
47 mBiasEstimator.processAccelerometer(acc, sensorTimeStamp);
50void OrientationTracker::processMag(
Vector3d mag, int64_t sensorTimeStamp)
52 mTracker.processMag(mag, sensorTimeStamp);
55void OrientationTracker::stopTracking()
59bool OrientationTracker::isReady()
61 return mTracker.isReady();
64Quaternion OrientationTracker::lastHeadView(
double timeOffsetInSeconds)
66 if (mLastGyroEventTimestamp == 0)
68 return Quaternion::IDENTITY;
71 double secondsSinceLastGyroEvent = (double)(GetTickCountNano() - mLastGyroEventTimestamp) * 1.e-09;
72 double secondsToPredictForward = secondsSinceLastGyroEvent + 0.016;
74 double* predictedMat = mTracker.getPredictedMatrix(secondsToPredictForward);
75 if (mNeckModelEnabled)
78 headmat = mNeckModelTranslation * headmat;
79 headmat.convert(predictedMat);
82 Quaternion frameQuat = Quaternion::FromRotationMatrix(predictedMat);
84 return Quaternion::IDENTITY;
86 frameQuat = mInertialReferenceFrameFromWorld * frameQuat * mDisplayFromDevice;
90void OrientationTracker::updateDeviceOrientation(DeviceOrientation orientation)
92 if (orientation == ROTATION_0)
94 mDisplayFromDevice =
Quaternion(1.0f, 0.0f, 0.0f, 0.0f);
96 else if (orientation == ROTATION_90)
99 mDisplayFromDevice =
Quaternion(sqrt(0.5f), 0.0f, 0.0f, sqrt(0.5f));
100 mDisplayFromDevice =
Quaternion(0.0f, 0.0f, 0.0f, 1.0f) * mDisplayFromDevice;
102 else if (orientation == ROTATION_180)
104 mDisplayFromDevice =
Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
106 else if (orientation == ROTATION_270)
109 mDisplayFromDevice =
Quaternion(sqrt(0.5f), 0.0f, 0.0f, sqrt(0.5f));
113bool OrientationTracker::neckModelEnabled()
115 return mNeckModelEnabled;
118void OrientationTracker::setNeckModelEnabled(
bool enabled)
120 mNeckModelEnabled = enabled;