⚡ Recommended focus areas for review
Possible Issue
In accComputeYaw, variables are redeclared and undefined identifiers are used (e.g., reusing pitch_change/roll_change and referencing raw_changed, self without definition). Also the return expression 'return yaw + 360 % 360' likely lacks parentheses, leading to incorrect normalization.
let pitch_change = changed[0];
let roll_change = changed[1];
// Normalize angles to -180 to 180 range for atan2
if (pitch_change > 180) pitch_change -= 360;
if (roll_change > 180) roll_change -= 360;
// Calculate yaw based on which axis changed when nose was lifted
let yaw = Math.atan2(-pitch_change, roll_change) * (180 / Math.PI);
// Adjust for upside down mounting
if (upside === 'down') {
yaw = (yaw + 180) % 360;
}
// Normalize to 0-360 range
yaw = (yaw + 360) % 360;
// Check for 45° mounting (25.5mm boards)
let corner_raised = false;
let pitch_change = Math.abs(raw_changed[0]);
let roll_change = Math.abs(raw_changed[1]);
if (pitch_change > 20 && pitch_change < 40 &&
roll_change > 20 && roll_change < 40 &&
Math.abs(pitch_change - roll_change) < 15) {
corner_raised = true;
}
if (corner_raised) {
yaw = Math.round(yaw / 22.5) * 22.5;
} else {
yaw = Math.round(yaw / 45) * 45;
}
return yaw + 360 % 360;
}
Runtime Errors
accComputeYaw function is defined twice (one in magnetometer-ai.js and another local). The local version uses nested object lookups without guarding for undefined subkeys, which can throw if corrections[upside][changed[0]] is undefined. Also comparisons like 'if (acc_g_45 < 0)' compare array to number; likely intended Z component.
function accComputeYaw(changed, upside) {
// Is upside down just -1 X the upside up value?
var corrections = {
'up': {
0: {
45: -90, // Confirmed
135: 0, // Double check
180: 0, // Double check
315: 90 // Confirmed
},
22: {
22: -45,
338: 45
},
45: {
0: 0, // Confirmed
45: -45,
90: -90,
270: 90 // May be upside down
},
315: {
0: 180, // Confirmed
90: -90,
270: 90
},
338: {
22: -135, // aka 225
338: 135
}
},
'down': {
0: {
45: -90 // 90?
},
45: {
0: -90 // Double check
}
}
};
if (typeof corrections[upside][changed[0]][changed[1]] != 'undefined') {
console.log(corrections[upside][changed[0]][changed[1]]);
return (corrections[upside][changed[0]][changed[1]]);
} else {
return(-1);
}
}
function accAutoAlignReadFlat() {
// this.heading_flat = SENSOR_DATA.kinematics[2];
let acc_g_flat = [...SENSOR_DATA.accelerometer];
let A = Math.sqrt(acc_g_flat[0] ** 2 + acc_g_flat[1] ** 2 + acc_g_flat[2] ** 2);
if (A > 1.15 || A < 0.85) {
modal = new jBox('Modal', {
width: 460,
height: 360,
animation: false,
closeOnClick: true,
content: $('#modal-acc-align-calibration-error')
}).open();
return;
}
let roll = (Math.atan2(acc_g_flat[1], acc_g_flat[2]) * 180/Math.PI + 360) % 360;
let pitch = ( Math.atan2(-1 * acc_g_flat[0], Math.sqrt(acc_g_flat[1] ** 2 + acc_g_flat[2] ** 2)) * 180/Math.PI +
360) % 360;
self.acc_flat_xyz = new Array(pitch, roll, 0);
console.log("pitch: " + pitch + ", roll: " + roll);
this.heading_flat = getMagHeading();
modal = new jBox('Modal', {
width: 460,
height: 360,
animation: false,
closeOnClick: false,
content: $('#modal-acc-align-45')
}).open();
}
function normalizeAngle(angle) {
return (angle + 360) % 360;
}
function accAutoAlignRead45() {
var changed = [0, 0, 0];
let raw_changed = [0, 0, 0];
var acc_align;
var i;
let acc_g_45 = [...SENSOR_DATA.accelerometer];
let roll = Math.atan2(acc_g_45[1], acc_g_45[2]) * 180/Math.PI;
let pitch = Math.atan2(-1 * acc_g_45[0], Math.sqrt(acc_g_45[1] ** 2 + acc_g_45[2] ** 2)) * 180/Math.PI;
let acc_45_xyz = new Array(pitch, roll, 0);
for (i = 0; i < acc_g_45.length; i++) {
self.acc_flat_xyz[i] = Math.round( self.acc_flat_xyz[i] / 45 ) * 45;
raw_changed[i] = self.acc_flat_xyz[i] - acc_45_xyz[i];
}
console.log("raw_changed: " + raw_changed);
// Check for 45° mounting (25.5mm boards)
let corner_raised = false;
let pitch_change = Math.abs(raw_changed[0]);
let roll_change = Math.abs(raw_changed[1]);
if (pitch_change > 20 && pitch_change < 40 &&
roll_change > 20 && roll_change < 40 &&
Math.abs(pitch_change - roll_change) < 15) {
corner_raised = true;
}
for (i = 0; i < 2; i++) {
if (corner_raised) {
changed[i] = ( 360 + Math.round(raw_changed[i] / 22) * 22 ) % 360;
} else {
changed[i] = ( 360 + Math.round(raw_changed[i] / 45) * 45 ) % 360;
}
}
// var boardRotation = new THREE.Euler( THREE.Math.degToRad( -self.boardAlignmentConfig.pitch ), THREE.Math.degToRad( -self.boardAlignmentConfig.yaw ), THREE.Math.degToRad( -self.boardAlignmentConfig.roll ), 'YXZ');
// var matrix1 = (new THREE.Matrix4()).makeRotationFromEuler(boardRotation);
/*
Get the actual down direction.
Get which edge or corner was lifted.
Define front as the edge or corner that was lifted.
Define the absolute orientation as that which has the correct part down and the correct part front.
Apply sensor orientation on the board.
Rotate the current settings according to the needed correction matrix.
OR
Get the rotation needed so that pitch and roll are near zero.
Define front as the edge or corner that was lifted.
Define the relative orientation (correction needed) as that which has the correct part down and the correct part front. (Relative to current settings).
Rotate the current settings according to the needed correction matrix.
*/
// console.log(axis);
// planet.position.applyQuaternion(quaternion);
let upside = 'up';
if (acc_g_45 < 0) { // Z acceleration is negative when upside down
upside = 'down';
}
console.log("changed:");
console.log(changed);
console.log("upside: " + upside);
let acc_yaw = accComputeYaw(changed, upside);
self.acc_flat_xyz[2] = acc_yaw;
Logic/Math Issues
Heading/angle normalization and modulo usage are inconsistent; some paths use negative angles without normalization, and expressions like '(self.mag_saved_yaw + correction_needed) % 360' can yield negative values. Ensure consistent normalizeAngle usage and correct operator precedence in logging and modulo operations.
function accAutoAlignCompass() {
let heading_change = (SENSOR_DATA.kinematics[2] - this.heading_flat + 360) % 360;
// let correction_needed = (450 - SENSOR_DATA.kinematics[2]) % 360;
let correction_needed = (90 - SENSOR_DATA.kinematics[2]);
// let heading_change = Math.round(heading_change / 90) * 90;
if ( typeof modal != "undefined" ) {
modal.close();
}
// If a 90 degree turn caused a 270 degree change, it's upside down.
if (heading_change > 180) {
console.log("mag upside down");
var rollCurrent90 = Math.round(self.mag_saved_roll / 90) * 90;
// let newRoll = (rollCurrent90 - 180) % 360;
updateRollAxis( (rollCurrent90 - 180) % 360 );
// ? correction_needed = correction_needed + 180;
}
// If both headings are accurate along a 45° offset, use that. Otherwise round to nearest 90°
if ( (Math.abs(this.heading_flat % 45) < 15) && Math.abs(correction_needed % 45) < 15 ) {
correction_needed = ( Math.round(correction_needed / 45) * 45 ) % 360;
} else {
correction_needed = ( Math.round(correction_needed / 90) * 90 ) % 360;
}
console.log("heading_flat: " + this.heading_flat + ", change: " + heading_change + ", correction: " + correction_needed % 360);
// let newYaw = (self.mag_saved_yaw + correction_needed) % 360;
updateYawAxis( (self.mag_saved_yaw + correction_needed) % 360 );
updatePitchAxis(self.mag_saved_pitch);
$("#modal-compass-align-setting").text(
self.alignmentConfig.roll + ", " + self.mag_saved_pitch + ", " + self.alignmentConfig.yaw
);
modal = new jBox('Modal', {
width: 460,
height: 360,
animation: false,
closeOnClick: true,
content: $('#modal-acc-align-done')
}).open();
}
|