, 0). This allows the tracker to be strapped to body at any pitch and
* roll.
*
* Performs {@link #resetYaw(Quaternion)} for yaw drift correction.
@@ -43,12 +50,12 @@ public class ReferenceAdjustedTracker implements Tracker {
@Override
public void resetFull(Quaternion reference) {
tracker.resetFull(reference);
- fixGyroscope();
Quaternion sensorRotation = new Quaternion();
tracker.getRotation(sensorRotation);
- gyroFix.mult(sensorRotation, sensorRotation);
- attachmentFix.set(sensorRotation).inverseLocal();
+
+ fixGyroscope(sensorRotation.clone());
+ fixAttachment(sensorRotation.clone());
fixYaw(reference);
}
@@ -65,39 +72,69 @@ public class ReferenceAdjustedTracker implements Tracker {
fixYaw(reference);
}
+ private void fixGyroscope(Quaternion sensorRotation) {
+ sensorRotation.fromAngles(0, sensorRotation.getYaw(), 0);
+ gyroFix.set(sensorRotation).inverseLocal();
+ }
+
+ private void fixAttachment(Quaternion sensorRotation) {
+ gyroFix.mult(sensorRotation, sensorRotation);
+ attachmentFix.set(sensorRotation).inverseLocal();
+ }
+
+ @Override
+ public void resetMounting(boolean reverseYaw) {
+ tracker.resetMounting(reverseYaw);
+
+ // Get the current calibrated rotation
+ Quaternion buffer = new Quaternion();
+ tracker.getRotation(buffer);
+ gyroFix.mult(buffer, buffer);
+ buffer.multLocal(attachmentFix);
+
+ // Reset the vector for the rotation to point straight up
+ rotVector.set(0f, 1f, 0f);
+ // Rotate the vector by the quat, then flatten and normalize the vector
+ buffer.multLocal(rotVector).setY(0f).normalizeLocal();
+
+ // Calculate the yaw angle using tan
+ // Just use an angle offset of zero for unsolvable circumstances
+ float yawAngle = FastMath.isApproxZero(rotVector.x) && FastMath.isApproxZero(rotVector.z)
+ ? 0f
+ : FastMath.atan2(rotVector.x, rotVector.z);
+
+ // Make an adjustment quaternion from the angle
+ buffer.fromAngles(0f, reverseYaw ? yawAngle : yawAngle - FastMath.PI, 0f);
+
+ Quaternion lastRotAdjust = new Quaternion(mountRotFix);
+ mountRotFix.set(buffer);
+
+ // Get the difference from the last adjustment
+ buffer.multLocal(lastRotAdjust.inverseLocal());
+ // Apply the yaw rotation difference to the yaw fix quaternion
+ yawFix.multLocal(buffer.inverseLocal());
+ }
+
private void fixYaw(Quaternion reference) {
// Use only yaw HMD rotation
- Quaternion targetTrackerRotation = new Quaternion(reference);
- float[] angles = new float[3];
- targetTrackerRotation.toAngles(angles);
- targetTrackerRotation.fromAngles(0, angles[1], 0);
+ Quaternion targetRotation = new Quaternion(reference);
+ targetRotation.fromAngles(0, targetRotation.getYaw(), 0);
Quaternion sensorRotation = new Quaternion();
tracker.getRotation(sensorRotation);
gyroFix.mult(sensorRotation, sensorRotation);
sensorRotation.multLocal(attachmentFix);
+ sensorRotation.multLocal(mountRotFix);
- sensorRotation.toAngles(angles);
- sensorRotation.fromAngles(0, angles[1], 0);
+ sensorRotation.fromAngles(0, sensorRotation.getYaw(), 0);
- yawFix.set(sensorRotation).inverseLocal().multLocal(targetTrackerRotation);
- }
-
- private void fixGyroscope() {
- float[] angles = new float[3];
-
- Quaternion sensorRotation = new Quaternion();
- tracker.getRotation(sensorRotation);
-
- sensorRotation.toAngles(angles);
- sensorRotation.fromAngles(0, angles[1], 0);
-
- gyroFix.set(sensorRotation).inverseLocal();
+ yawFix.set(sensorRotation).inverseLocal().multLocal(targetRotation);
}
protected void adjustInternal(Quaternion store) {
gyroFix.mult(store, store);
store.multLocal(attachmentFix);
+ store.multLocal(mountRotFix);
yawFix.mult(store, store);
}
diff --git a/server/src/main/java/dev/slimevr/vr/trackers/Tracker.java b/server/src/main/java/dev/slimevr/vr/trackers/Tracker.java
index b870f59e4..840a2db0a 100644
--- a/server/src/main/java/dev/slimevr/vr/trackers/Tracker.java
+++ b/server/src/main/java/dev/slimevr/vr/trackers/Tracker.java
@@ -36,6 +36,8 @@ public interface Tracker {
void resetYaw(Quaternion reference);
+ void resetMounting(boolean reverseYaw);
+
void tick();
TrackerPosition getBodyPosition();