1
0
Fork 0
mirror of https://github.com/iNavFlight/inav-configurator.git synced 2025-07-25 17:25:14 +03:00

Merge pull request #1806 from RomanLut/submit-fc-display

magnetometer alignment tool => alignment tool
This commit is contained in:
Paweł Spychalski 2023-09-19 13:32:10 +02:00 committed by GitHub
commit b738fdb22a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 468 additions and 205 deletions

View file

@ -900,18 +900,6 @@
"configurationSerialRXHelp": { "configurationSerialRXHelp": {
"message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) for the serial receiver" "message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) for the serial receiver"
}, },
"configurationBoardAlignment": {
"message": "Board and Sensor Alignment"
},
"configurationBoardAlignmentRoll": {
"message": "Roll Degrees"
},
"configurationBoardAlignmentPitch": {
"message": "Pitch Degrees"
},
"configurationBoardAlignmentYaw": {
"message": "Yaw Degrees"
},
"configurationSensorAlignmentMag": { "configurationSensorAlignmentMag": {
"message": "MAG Alignment" "message": "MAG Alignment"
}, },
@ -2035,19 +2023,22 @@
"message": "Signal Strength" "message": "Signal Strength"
}, },
"magnetometerHead": { "magnetometerHead": {
"message": "Magnetometer Alignment" "message": "Alignment tool"
}, },
"magnetometerHelp": { "magnetometerHelp": {
"message": "Adjust the magnetometer orientation to match physical orientation on the aircraft.<br/>If magnetometer is not BN-880, adjust according to \"compass direction\" arrow or axis markings on your magnetometer model.<br/><strong>Note:</strong> Magnetometer alignment is relative to FC. Make sure to align FC first (board_align_yaw, board_align_pitch, board_align_roll)." "message": "1. Adjust Flight Controller orientation to match physical orientation on the aircraft <u>according to \"direction\" arrow on Flight Controller</u>.<br/>2. Adjust magnetometer orientation to match physical orientation on the aircraft <u>according to \"compass direction\" arrow or axis markings on magnetometer</u>.<br/><strong>Note:</strong> Magnetometer orientation preset (align_mag) is relative to FC. Make sure to align FC first (align_board_pitch, align_board_roll, align_board_yaw).<br/>If preset is not used (orientation is set using align_mag_roll, align_mag_pitch and align_mag_yaw), then magnetometer orientation is independent."
}, },
"magnetometerOrientationPreset": { "magnetometerOrientationPreset": {
"message": "Orientation presets" "message": "Orientation preset (align_mag). Relative to FC orientation"
},
"boardInfo": {
"message": "1. Select Flight Controller alignment<br>(align_board_roll, align_board_pitch, align_board_yaw)"
}, },
"magnetometerInfo": { "magnetometerInfo": {
"message": "Select a preset or create a custom configuration moving the sliders" "message": "2. Select a preset (align_mag) or create a custom configuration using the sliders<br>(align_mag_roll, align_mag_pitch, align_mag_yaw)"
}, },
"magnetometerElementToShow": { "magnetometerElementToShow": {
"message": "Element to show" "message": "Element to show: Magnetometer model or axes"
}, },
"axisTableTitleAxis": { "axisTableTitleAxis": {
@ -2060,9 +2051,6 @@
"message": "Value [degree]" "message": "Value [degree]"
}, },
"configurationMagnetometerHelp": { "configurationMagnetometerHelp": {
"message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) when using the Magnetometer feature." "message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) when using the Magnetometer feature."
}, },
@ -2070,7 +2058,7 @@
"message": "Mag Statistics" "message": "Mag Statistics"
}, },
"tabMAGNETOMETER": { "tabMAGNETOMETER": {
"message": "Magnetometer" "message": "Alignment tool"
}, },
"motors": { "motors": {
"message": "Motors" "message": "Motors"
@ -4826,9 +4814,6 @@
"WaypointOptionP2": { "WaypointOptionP2": {
"message": "P2" "message": "P2"
}, },
"rollPitchAdjustmentsMoved": {
"message": "Roll & Pitch board orientation is available only in the CLI. Do not use it to trim the airplane for the level flight! Use Fixed Wing Level Trim on the PID tuning tab under Mechanics instead (<strong>fw_level_pitch_trim</strong>)."
},
"pidId": { "pidId": {
"message": "#" "message": "#"
}, },

View file

@ -136,8 +136,9 @@
.tab-magnetometer #interactive_block { .tab-magnetometer #interactive_block {
position: absolute; position: absolute;
width: calc(100% - 40px); width: calc(100% - 655px);
height: calc(100% - 245px); height: 771px;
min-height: calc(100% - 200px);
background-color: #f9f9f9; background-color: #f9f9f9;
border-radius: 5px; border-radius: 5px;
border: 1px solid #e4e4e4; border: 1px solid #e4e4e4;
@ -190,6 +191,17 @@ progress[value]::-webkit-progress-value {
box-shadow: 0 0 3px rgba(0, 0, 0, 0.25) inset; box-shadow: 0 0 3px rgba(0, 0, 0, 0.25) inset;
} }
.tab-magnetometer-left-wrapper {
float:left;
width: calc( 100% - 655px );
}
.tab-magnetometer-right-wrapper {
float:right;
width: 600px;
}
@media only screen and (max-width: 1055px) , only screen and (max-device-width: 1055px) { @media only screen and (max-width: 1055px) , only screen and (max-device-width: 1055px) {
#magnetometer-map { #magnetometer-map {

View file

@ -40,6 +40,21 @@
float: left; float: left;
} }
.attitude_note1 {
position: absolute;
left: 130px;
top: 29px;
font-size: 10px;
}
.attitude_note2 {
position: absolute;
left: 130px;
top: 13px;
font-size: 10px;
}
#interactive_block a.reset { #interactive_block a.reset {
position: absolute; position: absolute;
display: block; display: block;

View file

@ -54,28 +54,6 @@
</div> </div>
</div> </div>
<div class="board gui_box grey">
<div class="gui_box_titlebar">
<div class="spacer_box_title" data-i18n="configurationBoardAlignment"></div>
<div class="helpicon cf_tip" data-i18n_title="configHelp2"></div>
</div>
<div class="spacer_box">
<div class="info-box" data-i18n="rollPitchAdjustmentsMoved"></div>
<div class="number">
<input id="board_align_yaw" type="number" name="board_align_yaw" step="0.1" min="-180" max="360" />
<div class="alignicon yaw"></div>
<label for="board_align_yaw" data-i18n="configurationBoardAlignmentYaw"></label>
</div>
<div class="select" style="position: relative; top: -3px;">
<select id="magalign" class="magalign">
<option value="0">Default</option>
<!-- list generated here -->
</select>
<div class="alignicon yaw"></div>
<label for="magalign" data-i18n="configurationSensorAlignmentMag"></label>
</div>
</div>
</div>
<div class="config-section gui_box grey other"> <div class="config-section gui_box grey other">
<div class="gui_box_titlebar"> <div class="gui_box_titlebar">

View file

@ -30,12 +30,10 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
var saveChainer = new MSPChainerClass(); var saveChainer = new MSPChainerClass();
var saveChain = [ var saveChain = [
mspHelper.saveSensorAlignment,
mspHelper.saveAccTrim, mspHelper.saveAccTrim,
mspHelper.saveArmingConfig, mspHelper.saveArmingConfig,
mspHelper.saveAdvancedConfig, mspHelper.saveAdvancedConfig,
mspHelper.saveVTXConfig, mspHelper.saveVTXConfig,
mspHelper.saveBoardAlignment,
mspHelper.saveCurrentMeterConfig, mspHelper.saveCurrentMeterConfig,
mspHelper.saveMiscV2, mspHelper.saveMiscV2,
saveSettings, saveSettings,
@ -115,14 +113,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
// translate to user-selected language // translate to user-selected language
localize(); localize();
let alignments = FC.getSensorAlignments();
let orientation_mag_e = $('select.magalign');
for (i = 0; i < alignments.length; i++) {
orientation_mag_e.append('<option value="' + (i + 1) + '">' + alignments[i] + '</option>');
}
orientation_mag_e.val(SENSOR_ALIGNMENT.align_mag);
// VTX // VTX
var config_vtx = $('.config-vtx'); var config_vtx = $('.config-vtx');
if (VTX_CONFIG.device_type != VTX.DEV_UNKNOWN) { if (VTX_CONFIG.device_type != VTX.DEV_UNKNOWN) {
@ -209,7 +199,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
$('input[name="board_align_yaw"]').val((BOARD_ALIGNMENT.yaw / 10.0).toFixed(1)); $('input[name="board_align_yaw"]').val((BOARD_ALIGNMENT.yaw / 10.0).toFixed(1));
// fill magnetometer // fill magnetometer
$('#mag_declination').val(MISC.mag_declination); //UPDATE: moved to GPS tab and hidden
//$('#mag_declination').val(MISC.mag_declination);
// fill battery voltage // fill battery voltage
$('#voltagesource').val(MISC.voltage_source); $('#voltagesource').val(MISC.voltage_source);
@ -264,7 +255,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
$i2cSpeed.change(); $i2cSpeed.change();
$('a.save').click(function () { $('a.save').click(function () {
MISC.mag_declination = parseFloat($('#mag_declination').val()); //UPDATE: moved to GPS tab and hidden
//MISC.mag_declination = parseFloat($('#mag_declination').val());
ARMING_CONFIG.auto_disarm_delay = parseInt($('input[name="autodisarmdelay"]').val()); ARMING_CONFIG.auto_disarm_delay = parseInt($('input[name="autodisarmdelay"]').val());
@ -281,8 +273,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
MISC.battery_capacity_critical = parseInt($('#battery_capacity_critical').val() * MISC.battery_capacity / 100); MISC.battery_capacity_critical = parseInt($('#battery_capacity_critical').val() * MISC.battery_capacity / 100);
MISC.battery_capacity_unit = $('#battery_capacity_unit').val(); MISC.battery_capacity_unit = $('#battery_capacity_unit').val();
SENSOR_ALIGNMENT.align_mag = parseInt(orientation_mag_e.val());
googleAnalytics.sendEvent('Setting', 'I2CSpeed', $('#i2c_speed').children("option:selected").text()); googleAnalytics.sendEvent('Setting', 'I2CSpeed', $('#i2c_speed').children("option:selected").text());
googleAnalytics.sendEvent('Board', 'Accelerometer', $('#sensor-acc').children("option:selected").text()); googleAnalytics.sendEvent('Board', 'Accelerometer', $('#sensor-acc').children("option:selected").text());
@ -300,7 +290,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
helper.features.reset(); helper.features.reset();
helper.features.fromUI($('.tab-configuration')); helper.features.fromUI($('.tab-configuration'));
helper.features.execute(function () { helper.features.execute(function () {
BOARD_ALIGNMENT.yaw = Math.round(parseFloat($('input[name="board_align_yaw"]').val()) * 10);
CURRENT_METER_CONFIG.scale = parseInt($('#currentscale').val()); CURRENT_METER_CONFIG.scale = parseInt($('#currentscale').val());
CURRENT_METER_CONFIG.offset = Math.round(parseFloat($('#currentoffset').val()) * 10); CURRENT_METER_CONFIG.offset = Math.round(parseFloat($('#currentoffset').val()) * 10);
saveChainer.execute(); saveChainer.execute();

View file

@ -1,109 +1,188 @@
<div class="tab-magnetometer"> <div class="tab-magnetometer toolbar_fixed_bottom">
<div class="content_wrapper" style="height: calc(80% - 40px)"> <div class="content_wrapper">
<div class="tab_title" data-i18n="tabMagnetometer">Magnetometer</div> <div class="tab_title" data-i18n="tabMagnetometer">Magnetometer</div>
<div class="note spacebottom"> <div class="note spacebottom">
<div class="note_spacer"> <div class="note_spacer">
<p i18n="magnetometerHelp"></p> <p i18n="magnetometerHelp"></p>
</div> </div>
</div> </div>
<div style="height: calc(100% - 150px);"> <div class="cf_column tab-magnetometer-left-wrapper">
<div id="model"> <div class="model-and-info">
<div class="model-and-info"> <div id="interactive_block">
<div id="interactive_block"> <div id="canvas_wrapper">
<div id="canvas_wrapper"> <canvas id="canvas"></canvas>
<canvas id="canvas"></canvas> <div class="attitude_info">
<dl>
<dt>Heading:</dt>
<dd class="heading">&nbsp;</dd>
<dt>Pitch:</dt>
<dd class="pitch">&nbsp;</dd>
<dt>Roll:</dt>
<dd class="roll">&nbsp;</dd>
</dl>
</div> </div>
<a class="reset" href="#" data-i18n="initialSetupButtonResetZaxis"></a> <div class="attitude_note1" >(Values according to <b>saved</b> settings)</div>
<div class="attitude_note2" >(North: 0, East: 90, South: 180, West: 270)</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="config-section gui_box grey"> <div class="cf_column tab-magnetometer-right-wrapper">
<div class="spacer_box"> <div class="config-section gui_box grey">
<div id="alignment-info" class="info-box"> <div class="spacer_box">
<span data-i18n="magnetometerInfo"></span> <div id="board-alignment-info" class="info-box">
</div> <span data-i18n="boardInfo"></span>
<div class="select" style="display: flex; justify-content: left;"> </div>
<select id="magalign" class="magalign">
<option value="0">Default</option>
<!-- list generated here -->
</select>
<label for="magalign" data-i18n="magnetometerOrientationPreset"></label>
</div>
<div class="select" style="display: flex; justify-content: left;">
<select id="element_to_show">
<option value="0" selected>Magnetometer</option>
<option value="1">XYZ</option>
<!-- list generated here -->
</select>
<label for="element_to_show" data-i18n="magnetometerElementToShow"></label>
</div>
<table class="axis-table"> <table class="axis-table">
<thead> <thead>
<tr> <tr>
<td style="width: 5%; padding-bottom: 10px;"> <td style="width: 5%; padding-bottom: 10px;">
<p class="table-title"> <p class="table-title">
<span data-i18n="axisTableTitleAxis"></span> <span data-i18n="axisTableTitleAxis"></span>
</p> </p>
</td> </td>
<td style="width: 90%; padding-bottom: 10px;"> <td style="width: 90%; padding-bottom: 10px;">
<p class="table-title"> <p class="table-title">
<span data-i18n="axisTableTitleSlider"></span> <span data-i18n="axisTableTitleSlider"></span>
</p> </p>
</td> </td>
<td style="width: 5%; padding-bottom: 10px;"> <td style="width: 5%; padding-bottom: 10px;">
<a class="table-title"> <a class="table-title">
<span data-i18n="axisTableTitleValue"></span> <span data-i18n="axisTableTitleValue"></span>
</a> </a>
</td> </td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td class="info"> <td class="info">
<p class="title" data-i18n="configurationSensorAlignmentMagPitch"></p> <p class="title" data-i18n="configurationSensorAlignmentMagRoll"></p>
</td> </td>
<td> <td>
<div id="roll_slider" class="slider"></div> <div id="board_roll_slider" class="slider"></div>
</td> </td>
<td> <td>
<input type="number" id="alignRoll" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="180" /> <input type="number" id="boardAlignRoll" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="info"> <td class="info">
<p class="title" data-i18n="configurationSensorAlignmentMagRoll"></p> <p class="title" data-i18n="configurationSensorAlignmentMagPitch" style="margin: 5px"></p>
</td> </td>
<td> <td>
<div id="pitch_slider" class="slider"></div> <div id="board_pitch_slider" class="slider"></div>
</td> </td>
<td> <td>
<input type="number" id="alignPitch" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="180" /> <input type="number" id="boardAlignPitch" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="info"> <td class="info">
<p class="title" data-i18n="configurationSensorAlignmentMagYaw"></p> <p class="title" data-i18n="configurationSensorAlignmentMagYaw"></p>
</td> </td>
<td> <td>
<div id="yaw_slider" class="slider"></div> <div id="board_yaw_slider" class="slider"></div>
</td> </td>
<td> <td>
<input type="number" id="alignYaw" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" /> <input type="number" id="boardAlignYaw" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
</div>
<div class="config-section gui_box grey">
<div class="spacer_box">
<div id="alignment-info" class="info-box">
<span data-i18n="magnetometerInfo"></span>
</div>
<div class="select" style="display: flex; justify-content: left;">
<select id="magalign" class="magalign">
<option value="0">Default</option>
<!-- list generated here -->
</select>
<label for="magalign" data-i18n="magnetometerOrientationPreset"></label>
</div>
<div class="select" style="display: flex; justify-content: left;">
<select id="element_to_show">
<option value="0" selected>Magnetometer</option>
<option value="1">XYZ</option>
<!-- list generated here -->
</select>
<label for="element_to_show" data-i18n="magnetometerElementToShow"></label>
</div>
<table class="axis-table">
<thead>
<tr>
<td style="width: 5%; padding-bottom: 10px;">
<p class="table-title">
<span data-i18n="axisTableTitleAxis"></span>
</p>
</td>
<td style="width: 90%; padding-bottom: 10px;">
<p class="table-title">
<span data-i18n="axisTableTitleSlider"></span>
</p>
</td>
<td style="width: 5%; padding-bottom: 10px;">
<a class="table-title">
<span data-i18n="axisTableTitleValue"></span>
</a>
</td>
</tr>
</thead>
<tbody>
<tr>
<td class="info">
<p class="title" data-i18n="configurationSensorAlignmentMagRoll"></p>
</td>
<td>
<div id="roll_slider" class="slider"></div>
</td>
<td>
<input type="number" id="alignRoll" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
</td>
</tr>
<tr>
<td class="info">
<p class="title" data-i18n="configurationSensorAlignmentMagPitch" style="margin: 5px"></p>
</td>
<td>
<div id="pitch_slider" class="slider"></div>
</td>
<td>
<input type="number" id="alignPitch" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
</td>
</tr>
<tr>
<td class="info">
<p class="title" data-i18n="configurationSensorAlignmentMagYaw"></p>
</td>
<td>
<div id="yaw_slider" class="slider"></div>
</td>
<td>
<input type="number" id="alignYaw" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
</td>
</tr>
</tbody>
</table>
</div>
</div> </div>
</div> </div>
<div class="content_toolbar"> <div class="clear-both"></div>
<div class="btn save_btn"> </div>
<a class="save" href="#" data-i18n="configurationButtonSave"></a> <div class="content_toolbar supported hide">
</div> <div class="btn save_btn">
<a class="save" href="#" data-i18n="configurationButtonSave"></a>
</div> </div>
</div> </div>
</div> </div>
<div id="tab-auxiliary-templates"> <div id="tab-auxiliary-templates">

View file

@ -1,5 +1,5 @@
'use strict'; 'use strict';
/*global chrome,GUI,BOARD_ALIGNMENT,TABS,nwdialog,$*/ /*global chrome,GUI,BOARD_ALIGNMENT,TABS,nwdialog,helper,$*/
TABS.magnetometer = {}; TABS.magnetometer = {};
@ -18,6 +18,12 @@ TABS.magnetometer.initialize = function (callback) {
yaw: 0 yaw: 0
}; };
self.boardAlignmentConfig = {
pitch: 0,
roll: 0,
yaw: 0
};
self.pageElements = {}; self.pageElements = {};
self.isSavePreset = true; self.isSavePreset = true;
self.showMagnetometer = true; self.showMagnetometer = true;
@ -29,6 +35,12 @@ TABS.magnetometer.initialize = function (callback) {
var loadChain = [ var loadChain = [
mspHelper.loadMixerConfig, mspHelper.loadMixerConfig,
mspHelper.loadBoardAlignment, mspHelper.loadBoardAlignment,
function (callback) {
self.boardAlignmentConfig.pitch = Math.round(BOARD_ALIGNMENT.pitch / 10);
self.boardAlignmentConfig.roll = Math.round(BOARD_ALIGNMENT.roll / 10);
self.boardAlignmentConfig.yaw = Math.round(BOARD_ALIGNMENT.yaw / 10);
callback();
},
mspHelper.loadSensorAlignment, mspHelper.loadSensorAlignment,
// Pitch and roll must be inverted // Pitch and roll must be inverted
function (callback) { function (callback) {
@ -38,7 +50,7 @@ TABS.magnetometer.initialize = function (callback) {
}, },
function (callback) { function (callback) {
mspHelper.getSetting("align_mag_pitch").then(function (data) { mspHelper.getSetting("align_mag_pitch").then(function (data) {
self.alignmentConfig.pitch = (parseInt(data.value, 10) / 10) - 180; self.alignmentConfig.pitch = parseInt(data.value, 10) / 10;
}).then(callback) }).then(callback)
}, },
function (callback) { function (callback) {
@ -52,12 +64,27 @@ TABS.magnetometer.initialize = function (callback) {
loadChainer.setExitPoint(load_html); loadChainer.setExitPoint(load_html);
loadChainer.execute(); loadChainer.execute();
function areAnglesZero() {
return self.alignmentConfig.pitch === 0 && self.alignmentConfig.roll === 0 && self.alignmentConfig.yaw === 0
}
function isBoardAlignmentZero() {
return (self.boardAlignmentConfig.pitch == 0 ) && (self.boardAlignmentConfig.roll == 0 ) && (self.boardAlignmentConfig.yaw == 0);
}
//======================== //========================
// Save chain // Save chain
// ======================= // =======================
var saveChainer = new MSPChainerClass(); var saveChainer = new MSPChainerClass();
var saveChain = [ var saveChain = [
function (callback) {
BOARD_ALIGNMENT.pitch = self.boardAlignmentConfig.pitch * 10;
BOARD_ALIGNMENT.roll = self.boardAlignmentConfig.roll * 10;
BOARD_ALIGNMENT.yaw = self.boardAlignmentConfig.yaw * 10;
callback();
},
mspHelper.saveBoardAlignment,
// Magnetometer alignment // Magnetometer alignment
function (callback) { function (callback) {
let orientation_mag_e = $('select.magalign'); let orientation_mag_e = $('select.magalign');
@ -66,7 +93,7 @@ TABS.magnetometer.initialize = function (callback) {
}, },
mspHelper.saveSensorAlignment, mspHelper.saveSensorAlignment,
// Pitch/Roll/Yaw // Pitch/Roll/Yaw
// Pitch and roll must be inverted // Pitch and roll must be inverted - ???
function (callback) { function (callback) {
if (self.isSavePreset) if (self.isSavePreset)
mspHelper.setSetting("align_mag_roll", 0, callback); mspHelper.setSetting("align_mag_roll", 0, callback);
@ -77,14 +104,19 @@ TABS.magnetometer.initialize = function (callback) {
if (self.isSavePreset) if (self.isSavePreset)
mspHelper.setSetting("align_mag_pitch", 0, callback); mspHelper.setSetting("align_mag_pitch", 0, callback);
else else
mspHelper.setSetting("align_mag_pitch", (180 + self.alignmentConfig.pitch) * 10, callback); mspHelper.setSetting("align_mag_pitch", self.alignmentConfig.pitch * 10, callback);
}, },
function (callback) { function (callback) {
if (self.isSavePreset) if (self.isSavePreset)
mspHelper.setSetting("align_mag_yaw", 0, callback); mspHelper.setSetting("align_mag_yaw", 0, callback);
else else {
mspHelper.setSetting("align_mag_yaw", self.alignmentConfig.yaw * 10, callback); var fix = 0;
if ( areAnglesZero() ) {
fix = 1; //if all angles are 0, then we have to save yaw = 1 (0.1 deg) to enforce usage of angles, not a usage of preset
}
mspHelper.setSetting("align_mag_yaw", self.alignmentConfig.yaw * 10 + fix, callback);
}
}, },
mspHelper.saveToEeprom mspHelper.saveToEeprom
]; ];
@ -118,35 +150,98 @@ TABS.magnetometer.initialize = function (callback) {
return arr; return arr;
} }
function toUpperRange(input, max) {
while (input > max) input -= 360;
while (input + 360 <= max) input += 360;
return input;
}
/* /*
Returns pitch, roll and yaw in degree by the id of a preset. Returns pitch, roll and yaw in degree by the id of a preset.
Degree are the ones used in the slider Degree are the ones used in the slider
*/ */
function getAxisDegreeWithPreset(selectedPreset) { function getAxisDegreeWithPreset(selectedPreset) {
//pitch, roll, yaw
switch (selectedPreset) { switch (selectedPreset) {
case 1: //CW0_DEG = 1 case 1: //CW0_DEG = 1
return [180, 0, 0];
case 2: //CW90_DEG = 2
return [180, 0, 90];
case 3: //CW180_DEG = 3
return [180, 0, 180];
case 4: //CW270_DEG = 4
return [180, 0, 270];
case 5: //CW0_DEG_FLIP = 5
return [0, 0, 0]; return [0, 0, 0];
case 6: //CW90_DEG_FLIP = 5 case 2: //CW90_DEG = 2
return [0, 0, 90]; return [0, 0, 90];
case 7: //CW180_DEG_FLIP = 5 case 3: //CW180_DEG = 3
return [0, 0, 180]; return [0, 0, 180];
case 4: //CW270_DEG = 4
return [0, 0, 270];
case 5: //CW0_DEG_FLIP = 5
return [180, 0, 0];
case 6: //CW90_DEG_FLIP = 5
return [180, 0, 90];
case 7: //CW180_DEG_FLIP = 5
return [180, 0, 180];
case 0: //ALIGN_DEFAULT = 0 case 0: //ALIGN_DEFAULT = 0
case 8: //CW270_DEG_FLIP = 5 case 8: //CW270_DEG_FLIP = 5
default://If not recognized, returns defualt default://If not recognized, returns defualt
return [0, 0, 270]; return [180, 0, 270];
} }
} }
function isUsingAPreset() { function getAxisDegreeWithPresetAndBoardOrientation(selectedPreset) {
return self.alignmentConfig.pitch === -180 && self.alignmentConfig.roll === 0 && self.alignmentConfig.yaw === 0 var degree = getAxisDegreeWithPreset(selectedPreset);
if (isBoardAlignmentZero()) {
return degree;
}
//degree[0] - pitch
//degree[1] - roll
//degree[2] - yaw
//-(pitch-180), -180 - yaw, roll
var magRotation = new THREE.Euler(-THREE.Math.degToRad(degree[0]-180), THREE.Math.degToRad(-180 - degree[2]), THREE.Math.degToRad(degree[1]), 'YXZ');
var matrix = (new THREE.Matrix4()).makeRotationFromEuler(magRotation);
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);
matrix.premultiply(matrix1);
var euler = new THREE.Euler();
euler.setFromRotationMatrix(matrix, 'YXZ');
var pitch = toUpperRange( Math.round( THREE.Math.radToDeg(-euler.x)) + 180, 180 );
var yaw = toUpperRange( Math.round( -180 - THREE.Math.radToDeg(euler.y)), 359 );
var roll = toUpperRange( Math.round( THREE.Math.radToDeg(euler.z)), 180 );
return [pitch, roll, yaw];
}
function updateMagOrientationWithPreset() {
if (self.isSavePreset) {
const degrees = getAxisDegreeWithPresetAndBoardOrientation(SENSOR_ALIGNMENT.align_mag);
presetUpdated(degrees);
}
}
function updateBoardRollAxis(value) {
self.boardAlignmentConfig.roll = Number(value);
self.pageElements.board_roll_slider.val(self.boardAlignmentConfig.roll);
self.pageElements.orientation_board_roll.val(self.boardAlignmentConfig.roll);
updateMagOrientationWithPreset();
self.render3D();
}
function updateBoardPitchAxis(value) {
self.boardAlignmentConfig.pitch = Number(value);
self.pageElements.board_pitch_slider.val(self.boardAlignmentConfig.pitch);
self.pageElements.orientation_board_pitch.val(self.boardAlignmentConfig.pitch);
updateMagOrientationWithPreset();
self.render3D();
}
function updateBoardYawAxis(value) {
self.boardAlignmentConfig.yaw = Number(value);
self.pageElements.board_yaw_slider.val(self.boardAlignmentConfig.yaw);
self.pageElements.orientation_board_yaw.val(self.boardAlignmentConfig.yaw);
updateMagOrientationWithPreset();
self.render3D();
} }
//Called when roll values change //Called when roll values change
@ -173,10 +268,22 @@ TABS.magnetometer.initialize = function (callback) {
self.render3D(); self.render3D();
} }
//Called when a preset is selected function enableSavePreset() {
function presetUpdated(degrees) {
self.isSavePreset = true; self.isSavePreset = true;
self.pageElements.orientation_mag_e.css("opacity", 1); self.pageElements.orientation_mag_e.css("opacity", 1);
self.pageElements.orientation_mag_e.css("text-decoration", "");
}
function disableSavePreset() {
self.isSavePreset = false;
self.pageElements.orientation_mag_e.css("opacity", 0.5);
self.pageElements.orientation_mag_e.css("text-decoration", "line-through");
}
//Called when a preset is selected
function presetUpdated(degrees) {
enableSavePreset();
updatePitchAxis(degrees[0]); updatePitchAxis(degrees[0]);
updateRollAxis(degrees[1]); updateRollAxis(degrees[1]);
updateYawAxis(degrees[2]); updateYawAxis(degrees[2]);
@ -184,12 +291,21 @@ TABS.magnetometer.initialize = function (callback) {
function process_html() { function process_html() {
localize(); localize();
// initialize 3D // initialize 3D
self.initialize3D(); self.initialize3D();
let alignments = FC.getSensorAlignments(); let alignments = FC.getSensorAlignments();
self.pageElements.orientation_board_roll = $('#boardAlignRoll');
self.pageElements.orientation_board_pitch = $('#boardAlignPitch');
self.pageElements.orientation_board_yaw = $('#boardAlignYaw');
self.pageElements.board_roll_slider = $('#board_roll_slider');
self.pageElements.board_pitch_slider = $('#board_pitch_slider');
self.pageElements.board_yaw_slider = $('#board_yaw_slider');
self.pageElements.orientation_mag_e = $('select.magalign'); self.pageElements.orientation_mag_e = $('select.magalign');
self.pageElements.orientation_mag_roll = $('#alignRoll'); self.pageElements.orientation_mag_roll = $('#alignRoll');
self.pageElements.orientation_mag_pitch = $('#alignPitch'); self.pageElements.orientation_mag_pitch = $('#alignPitch');
@ -198,24 +314,97 @@ TABS.magnetometer.initialize = function (callback) {
self.pageElements.pitch_slider = $('#pitch_slider'); self.pageElements.pitch_slider = $('#pitch_slider');
self.pageElements.yaw_slider = $('#yaw_slider'); self.pageElements.yaw_slider = $('#yaw_slider');
self.roll_e = $('dd.roll'),
self.pitch_e = $('dd.pitch'),
self.heading_e = $('dd.heading');
for (i = 0; i < alignments.length; i++) { for (i = 0; i < alignments.length; i++) {
self.pageElements.orientation_mag_e.append('<option value="' + (i + 1) + '">' + alignments[i] + '</option>'); self.pageElements.orientation_mag_e.append('<option value="' + (i + 1) + '">' + alignments[i] + '</option>');
} }
self.pageElements.orientation_mag_e.val(SENSOR_ALIGNMENT.align_mag); self.pageElements.orientation_mag_e.val(SENSOR_ALIGNMENT.align_mag);
if (isUsingAPreset()) { if (areAnglesZero()) {
//If using a preset, checking if custom values are equal to 0 //If using a preset, checking if custom values are equal to 0
//Update the slider, but don't save the value until they will be not modified. //Update the slider, but don't save the value until they will be not modified.
const degrees = getAxisDegreeWithPreset(SENSOR_ALIGNMENT.align_mag); const degrees = getAxisDegreeWithPresetAndBoardOrientation(SENSOR_ALIGNMENT.align_mag);
presetUpdated(degrees); presetUpdated(degrees);
} }
else { else {
updateRollAxis(self.alignmentConfig.roll); updateRollAxis(self.alignmentConfig.roll);
updatePitchAxis(self.alignmentConfig.pitch); updatePitchAxis(self.alignmentConfig.pitch);
updateYawAxis(self.alignmentConfig.yaw); updateYawAxis(self.alignmentConfig.yaw);
self.pageElements.orientation_mag_e.css("opacity", 0.5); disableSavePreset();
} }
self.pageElements.orientation_board_roll.change(function () {
updateBoardRollAxis(clamp(this, -180, 360));
});
self.pageElements.orientation_board_pitch.change(function () {
updateBoardPitchAxis(clamp(this, -180, 360));
});
self.pageElements.orientation_board_yaw.change(function () {
updateBoardYawAxis(clamp(this, -180, 360));
});
self.pageElements.board_roll_slider.noUiSlider({
start: [self.boardAlignmentConfig.roll],
range: {
'min': [-180],
'max': [360]
},
step: 1,
});
self.pageElements.board_roll_slider.noUiSlider_pips({
mode: 'values',
values: generateRange(-180, 360, 45),
density: 4,
stepped: true
});
self.pageElements.board_pitch_slider.noUiSlider({
start: [self.boardAlignmentConfig.pitch],
range: {
'min': [-180],
'max': [360]
},
step: 1,
});
self.pageElements.board_pitch_slider.noUiSlider_pips({
mode: 'values',
values: generateRange(-180, 360, 45),
density: 4,
stepped: true
});
self.pageElements.board_yaw_slider.noUiSlider({
start: [self.boardAlignmentConfig.yaw],
range: {
'min': [-180],
'max': [360]
},
step: 1,
});
self.pageElements.board_yaw_slider.noUiSlider_pips({
mode: 'values',
values: generateRange(-180, 360, 45),
density: 4,
stepped: true
});
self.pageElements.board_pitch_slider.Link('lower').to((e) => {
updateBoardPitchAxis(e);
});
self.pageElements.board_roll_slider.Link('lower').to((e) => {
updateBoardRollAxis(e);
});
self.pageElements.board_yaw_slider.Link('lower').to((e) => {
updateBoardYawAxis(e);
});
const elementToShow = $("#element_to_show"); const elementToShow = $("#element_to_show");
elementToShow.change(function () { elementToShow.change(function () {
const value = parseInt($(this).val()); const value = parseInt($(this).val());
@ -229,28 +418,28 @@ TABS.magnetometer.initialize = function (callback) {
self.pageElements.orientation_mag_e.change(function () { self.pageElements.orientation_mag_e.change(function () {
SENSOR_ALIGNMENT.align_mag = parseInt($(this).val()); SENSOR_ALIGNMENT.align_mag = parseInt($(this).val());
const degrees = getAxisDegreeWithPreset(SENSOR_ALIGNMENT.align_mag); const degrees = getAxisDegreeWithPresetAndBoardOrientation(SENSOR_ALIGNMENT.align_mag);
presetUpdated(degrees);
});
self.pageElements.orientation_mag_e.on('mousedown', function () {
const degrees = getAxisDegreeWithPresetAndBoardOrientation(SENSOR_ALIGNMENT.align_mag);
presetUpdated(degrees); presetUpdated(degrees);
}); });
self.pageElements.orientation_mag_roll.change(function () { self.pageElements.orientation_mag_roll.change(function () {
self.isSavePreset = false; disableSavePreset();
self.pageElements.orientation_mag_e.css("opacity", 0.5); updateRollAxis(clamp(this, -180, 360));
updateRollAxis(clamp(this, -180, 180));
}); });
self.pageElements.orientation_mag_pitch.change(function () { self.pageElements.orientation_mag_pitch.change(function () {
self.isSavePreset = false; disableSavePreset();
self.pageElements.orientation_mag_e.css("opacity", 0.5); updatePitchAxis(clamp(this, -180, 360));
updatePitchAxis(clamp(this, -180, 180));
}); });
self.pageElements.orientation_mag_yaw.change(function () { self.pageElements.orientation_mag_yaw.change(function () {
self.isSavePreset = false; disableSavePreset();
self.pageElements.orientation_mag_e.css("opacity", 0.5);
updateYawAxis(clamp(this, -180, 360)); updateYawAxis(clamp(this, -180, 360));
}); });
$('a.save').click(function () { $('a.save').click(function () {
@ -261,13 +450,13 @@ TABS.magnetometer.initialize = function (callback) {
start: [self.alignmentConfig.roll], start: [self.alignmentConfig.roll],
range: { range: {
'min': [-180], 'min': [-180],
'max': [180] 'max': [360]
}, },
step: 1, step: 1,
}); });
self.pageElements.roll_slider.noUiSlider_pips({ self.pageElements.roll_slider.noUiSlider_pips({
mode: 'values', mode: 'values',
values: generateRange(-180, 180, 15), values: generateRange(-180, 360, 45),
density: 4, density: 4,
stepped: true stepped: true
}); });
@ -276,13 +465,13 @@ TABS.magnetometer.initialize = function (callback) {
start: [self.alignmentConfig.pitch], start: [self.alignmentConfig.pitch],
range: { range: {
'min': [-180], 'min': [-180],
'max': [180] 'max': [360]
}, },
step: 1, step: 1,
}); });
self.pageElements.pitch_slider.noUiSlider_pips({ self.pageElements.pitch_slider.noUiSlider_pips({
mode: 'values', mode: 'values',
values: generateRange(-180, 180, 15), values: generateRange(-180, 360, 45),
density: 4, density: 4,
stepped: true stepped: true
}); });
@ -293,7 +482,7 @@ TABS.magnetometer.initialize = function (callback) {
'min': [-180], 'min': [-180],
'max': [360] 'max': [360]
}, },
step: 45, step: 1,
}); });
self.pageElements.yaw_slider.noUiSlider_pips({ self.pageElements.yaw_slider.noUiSlider_pips({
mode: 'values', mode: 'values',
@ -302,6 +491,7 @@ TABS.magnetometer.initialize = function (callback) {
stepped: true stepped: true
}); });
self.pageElements.pitch_slider.Link('lower').to((e) => { self.pageElements.pitch_slider.Link('lower').to((e) => {
updatePitchAxis(e); updatePitchAxis(e);
}); });
@ -312,19 +502,31 @@ TABS.magnetometer.initialize = function (callback) {
updateYawAxis(e); updateYawAxis(e);
}); });
self.pageElements.pitch_slider.change((e) => { self.pageElements.pitch_slider.on('slide', (e) => {
self.isSavePreset = false; disableSavePreset();
self.pageElements.orientation_mag_e.css("opacity", 0.5);
}); });
self.pageElements.roll_slider.change((e) => { self.pageElements.roll_slider.on('slide', (e) => {
self.isSavePreset = false; disableSavePreset();
self.pageElements.orientation_mag_e.css("opacity", 0.5);
}); });
self.pageElements.yaw_slider.change((e) => { self.pageElements.yaw_slider.on('slide', (e) => {
self.isSavePreset = false; disableSavePreset();
self.pageElements.orientation_mag_e.css("opacity", 0.5);
}); });
function get_fast_data() {
if (helper.mspQueue.shouldDrop()) {
return;
}
MSP.send_message(MSPCodes.MSP_ATTITUDE, false, false, function () {
self.roll_e.text(chrome.i18n.getMessage('initialSetupAttitude', [SENSOR_DATA.kinematics[0]]));
self.pitch_e.text(chrome.i18n.getMessage('initialSetupAttitude', [SENSOR_DATA.kinematics[1]]));
self.heading_e.text(chrome.i18n.getMessage('initialSetupAttitude', [SENSOR_DATA.kinematics[2]]));
self.render3D();
});
}
helper.mspBalancedInterval.add('setup_data_pull_fast', 40, 1, get_fast_data);
GUI.content_ready(callback); GUI.content_ready(callback);
} }
@ -395,14 +597,17 @@ TABS.magnetometer.initialize3D = function () {
xyz.visible = !self.showMagnetometer; xyz.visible = !self.showMagnetometer;
fc.visible = true; fc.visible = true;
var magRotation = new THREE.Euler(-THREE.Math.degToRad(self.alignmentConfig.pitch), THREE.Math.degToRad(-180 - self.alignmentConfig.yaw), THREE.Math.degToRad(self.alignmentConfig.roll), 'YXZ'); var magRotation = new THREE.Euler(-THREE.Math.degToRad(self.alignmentConfig.pitch-180), THREE.Math.degToRad(-180 - self.alignmentConfig.yaw), THREE.Math.degToRad(self.alignmentConfig.roll), 'YXZ');
var matrix = (new THREE.Matrix4()).makeRotationFromEuler(magRotation); var matrix = (new THREE.Matrix4()).makeRotationFromEuler(magRotation);
var boardRotation = new THREE.Euler( THREE.Math.degToRad( -BOARD_ALIGNMENT.pitch / 10.0 ), THREE.Math.degToRad( -BOARD_ALIGNMENT.yaw / 10.0 ), THREE.Math.degToRad( -BOARD_ALIGNMENT.roll / 10.0 ), 'YXZ'); 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); var matrix1 = (new THREE.Matrix4()).makeRotationFromEuler(boardRotation);
matrix.multiply(matrix1);
/*
if ( self.isSavePreset ) {
matrix.premultiply(matrix1); //preset specifies orientation relative to FC, align_max_xxx specify absolute orientation
}
*/
gps.rotation.setFromRotationMatrix(matrix); gps.rotation.setFromRotationMatrix(matrix);
xyz.rotation.setFromRotationMatrix(matrix); xyz.rotation.setFromRotationMatrix(matrix);
fc.rotation.setFromRotationMatrix(matrix1); fc.rotation.setFromRotationMatrix(matrix1);