Skip to content

Commit ba1e751

Browse files
authored
Merge pull request #6 from dnathe4th/claude/compass-accuracy-fix-011CUu4h2RCLCqms8gH6haLQ
Fix compass accuracy for vertical phone orientation
2 parents 288cbbd + 4765559 commit ba1e751

File tree

1 file changed

+104
-9
lines changed

1 file changed

+104
-9
lines changed

ocean-crosser.html

Lines changed: 104 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,23 @@
149149
color: #FFD700;
150150
}
151151

152+
#sensor-debug {
153+
position: absolute;
154+
top: 10px;
155+
left: 10px;
156+
background: rgba(0, 0, 0, 0.8);
157+
padding: 10px;
158+
border-radius: 5px;
159+
font-size: 12px;
160+
font-family: monospace;
161+
z-index: 150;
162+
max-width: 200px;
163+
}
164+
165+
#sensor-debug div {
166+
margin: 2px 0;
167+
}
168+
152169
#destination {
153170
background: rgba(0, 0, 0, 0.5);
154171
padding: 20px;
@@ -225,6 +242,15 @@ <h1>🌊 Ocean Crosser</h1>
225242

226243
<div id="compass-container">
227244
<div id="compass">
245+
<div id="sensor-debug" style="display: none;">
246+
<div><strong>Raw Sensors:</strong></div>
247+
<div id="sensor-alpha">α: --</div>
248+
<div id="sensor-beta">β: --</div>
249+
<div id="sensor-gamma">γ: --</div>
250+
<div id="sensor-absolute">Absolute: --</div>
251+
<div id="sensor-webkit">WebKit: --</div>
252+
<div id="sensor-calculated">Calc: --</div>
253+
</div>
228254
<div id="heading-display">--°</div>
229255
<div id="crosshair"></div>
230256
<div id="compass-strip">
@@ -366,9 +392,17 @@ <h1>🌊 Ocean Crosser</h1>
366392
const locationInfoEl = document.getElementById('location-info');
367393
const startBtn = document.getElementById('start-btn');
368394
const debugEl = document.getElementById('debug');
395+
const sensorDebugEl = document.getElementById('sensor-debug');
396+
const sensorAlphaEl = document.getElementById('sensor-alpha');
397+
const sensorBetaEl = document.getElementById('sensor-beta');
398+
const sensorGammaEl = document.getElementById('sensor-gamma');
399+
const sensorAbsoluteEl = document.getElementById('sensor-absolute');
400+
const sensorWebkitEl = document.getElementById('sensor-webkit');
401+
const sensorCalculatedEl = document.getElementById('sensor-calculated');
369402

370403
if (debugMode) {
371404
debugEl.style.display = 'block';
405+
sensorDebugEl.style.display = 'block';
372406
}
373407

374408
// Create compass tape with cardinal directions
@@ -533,11 +567,42 @@ <h1>🌊 Ocean Crosser</h1>
533567
});
534568
}
535569

570+
// Calculate compass heading from device orientation for vertical phone position
571+
function calculateCompassHeading(alpha, beta, gamma) {
572+
// Convert to radians
573+
const alphaRad = toRadians(alpha);
574+
const betaRad = toRadians(beta);
575+
const gammaRad = toRadians(gamma);
576+
577+
// Calculate compass heading accounting for device tilt
578+
// This works when phone is held vertically (portrait mode)
579+
const compassHeading = Math.atan2(
580+
-Math.sin(gammaRad) * Math.cos(betaRad),
581+
Math.cos(gammaRad) * Math.cos(betaRad) * Math.cos(alphaRad) +
582+
Math.sin(betaRad) * Math.sin(alphaRad)
583+
);
584+
585+
// Convert to degrees and normalize to 0-360
586+
let heading = toDegrees(compassHeading);
587+
heading = (heading + 360) % 360;
588+
589+
return heading;
590+
}
591+
536592
// Handle device orientation
537593
let orientationEventCount = 0;
538594
function handleOrientation(event) {
539595
if (!isCompassActive || !userLocation) return;
540596

597+
// Update sensor debug display
598+
if (sensorDebugEl) {
599+
sensorAlphaEl.textContent = `α: ${event.alpha !== null ? event.alpha.toFixed(1) : 'null'}°`;
600+
sensorBetaEl.textContent = `β: ${event.beta !== null ? event.beta.toFixed(1) : 'null'}°`;
601+
sensorGammaEl.textContent = `γ: ${event.gamma !== null ? event.gamma.toFixed(1) : 'null'}°`;
602+
sensorAbsoluteEl.textContent = `Absolute: ${event.absolute ? 'yes' : 'no'}`;
603+
sensorWebkitEl.textContent = `WebKit: ${event.webkitCompassHeading !== undefined ? event.webkitCompassHeading.toFixed(1) + '°' : 'n/a'}`;
604+
}
605+
541606
// Log first event for debugging
542607
if (orientationEventCount === 0) {
543608
log(`First orientation event received - alpha: ${event.alpha}, beta: ${event.beta}, gamma: ${event.gamma}, webkitCompassHeading: ${event.webkitCompassHeading}`);
@@ -548,17 +613,28 @@ <h1>🌊 Ocean Crosser</h1>
548613
let heading = null;
549614

550615
if (event.webkitCompassHeading !== undefined) {
551-
// iOS
616+
// iOS - webkitCompassHeading is already calibrated
552617
heading = event.webkitCompassHeading;
553618
if (orientationEventCount === 1) log('Using iOS webkitCompassHeading');
554-
} else if (event.alpha !== null) {
555-
// Android
556-
heading = 360 - event.alpha;
557-
if (orientationEventCount === 1) log('Using Android alpha orientation');
619+
} else if (event.alpha !== null && event.beta !== null && event.gamma !== null) {
620+
// Android - calculate heading from orientation data
621+
// Check if phone is roughly vertical (beta between 45 and 135 degrees)
622+
if (Math.abs(event.beta) > 45 && Math.abs(event.beta) < 135) {
623+
// Phone is vertical - use proper calculation
624+
heading = calculateCompassHeading(event.alpha, event.beta, event.gamma);
625+
if (orientationEventCount === 1) log('Using calculated heading for vertical orientation');
626+
} else {
627+
// Phone is flat - use simple alpha
628+
heading = 360 - event.alpha;
629+
if (orientationEventCount === 1) log('Using simple alpha for flat orientation');
630+
}
558631
}
559632

560633
if (heading !== null) {
561634
currentHeading = heading;
635+
if (sensorDebugEl) {
636+
sensorCalculatedEl.textContent = `Calc: ${heading.toFixed(1)}°`;
637+
}
562638
// Apply smoothing to reduce jitter
563639
smoothedHeading = orientationEventCount === 1 ? heading : smoothHeading(heading, smoothedHeading);
564640
updateDisplay(Math.round(smoothedHeading));
@@ -573,12 +649,24 @@ <h1>🌊 Ocean Crosser</h1>
573649
if (!isCompassActive || !userLocation) return;
574650

575651
if (absoluteEventCount === 0) {
576-
log(`First absolute orientation event - absolute: ${event.absolute}, alpha: ${event.alpha}`);
652+
log(`First absolute orientation event - absolute: ${event.absolute}, alpha: ${event.alpha}, beta: ${event.beta}, gamma: ${event.gamma}`);
577653
}
578654
absoluteEventCount++;
579655

580-
if (event.absolute && event.alpha !== null) {
581-
let heading = 360 - event.alpha;
656+
if (event.absolute && event.alpha !== null && event.beta !== null && event.gamma !== null) {
657+
let heading = null;
658+
659+
// Check if phone is roughly vertical (beta between 45 and 135 degrees)
660+
if (Math.abs(event.beta) > 45 && Math.abs(event.beta) < 135) {
661+
// Phone is vertical - use proper calculation
662+
heading = calculateCompassHeading(event.alpha, event.beta, event.gamma);
663+
if (absoluteEventCount === 1) log('Using calculated heading for vertical orientation (absolute)');
664+
} else {
665+
// Phone is flat - use simple alpha
666+
heading = 360 - event.alpha;
667+
if (absoluteEventCount === 1) log('Using simple alpha for flat orientation (absolute)');
668+
}
669+
582670
currentHeading = heading;
583671
// Apply smoothing to reduce jitter
584672
smoothedHeading = absoluteEventCount === 1 ? heading : smoothHeading(heading, smoothedHeading);
@@ -681,11 +769,18 @@ <h1>🌊 Ocean Crosser</h1>
681769
log('Event listeners added');
682770

683771
isCompassActive = true;
684-
statusEl.textContent = 'Compass active - Point at the horizon';
772+
statusEl.innerHTML = 'Compass active - <span style="color: #FFD700;">Wave phone in figure-8 to calibrate</span>';
685773
startBtn.textContent = 'Compass Active';
686774

687775
log('=== Compass started successfully - waiting for orientation events ===');
688776

777+
// Show calibration reminder after 2 seconds
778+
setTimeout(() => {
779+
if (isCompassActive) {
780+
log('TIP: Wave your phone in a figure-8 pattern to calibrate the magnetometer');
781+
}
782+
}, 2000);
783+
689784
// Set a timeout to check if we're receiving events
690785
setTimeout(() => {
691786
if (orientationEventCount === 0 && absoluteEventCount === 0) {

0 commit comments

Comments
 (0)