mirror of
https://github.com/iNavFlight/inav-configurator.git
synced 2025-07-24 08:45:26 +03:00
commit
04612a94e8
17 changed files with 979 additions and 285 deletions
|
@ -1894,5 +1894,29 @@
|
|||
},
|
||||
"armingCheckFail": {
|
||||
"message": "<span class=\"arming-state-fail\">FAIL</span>"
|
||||
},
|
||||
"tabPresets": {
|
||||
"message": "Presets"
|
||||
},
|
||||
"presetsPreset": {
|
||||
"message": "Preset"
|
||||
},
|
||||
"presetsDescription": {
|
||||
"message": "Description"
|
||||
},
|
||||
"presetsButtonApply": {
|
||||
"message": "Apply"
|
||||
},
|
||||
"presetApplyTitle" : {
|
||||
"message": "Confirm"
|
||||
},
|
||||
"presetsButtonSaveAndReboot": {
|
||||
"message": "Save and reboot"
|
||||
},
|
||||
"presetsApplyHeader": {
|
||||
"message": "Warning"
|
||||
},
|
||||
"presetApplyDescription": {
|
||||
"message": "Preset overwrites selected configuration values including mixer, filtering, PIDs and other. Settings like: flight modes, radio settings, failsafe and OSD are not changed. Applied values should <strong>NOT</strong> treated as final values, but entry points for final tuning. <br> Always check new configuration before flying!"
|
||||
}
|
||||
}
|
8
js/fc.js
8
js/fc.js
|
@ -237,7 +237,13 @@ var FC = {
|
|||
FILTER_CONFIG = {
|
||||
gyroSoftLpfHz: null,
|
||||
dtermLpfHz: null,
|
||||
yawLpfHz: null
|
||||
yawLpfHz: null,
|
||||
gyroNotchHz1: null,
|
||||
gyroNotchCutoff1: null,
|
||||
dtermNotchHz: null,
|
||||
dtermNotchCutoff: null,
|
||||
gyroNotchHz2: null,
|
||||
gyroNotchCutoff2: null
|
||||
};
|
||||
|
||||
PID_ADVANCED = {
|
||||
|
|
|
@ -37,7 +37,8 @@ var GUI_control = function () {
|
|||
'sensors',
|
||||
'servos',
|
||||
'setup',
|
||||
'osd'
|
||||
'osd',
|
||||
'profiles'
|
||||
];
|
||||
this.allowedTabs = this.defaultAllowedTabsWhenDisconnected;
|
||||
|
||||
|
|
51
js/model.js
51
js/model.js
|
@ -2,30 +2,29 @@
|
|||
|
||||
// generate mixer
|
||||
var mixerList = [
|
||||
{name: 'Tricopter', model: 'tricopter', image: 'tri'},
|
||||
{name: 'Quad +', model: 'quad_x', image: 'quad_p'},
|
||||
{name: 'Quad X', model: 'quad_x', image: 'quad_x'},
|
||||
{name: 'Bicopter', model: 'custom', image: 'bicopter'},
|
||||
{name: 'Gimbal', model: 'custom', image: 'custom'},
|
||||
{name: 'Y6', model: 'y6', image: 'y6'},
|
||||
{name: 'Hex +', model: 'hex_plus', image: 'hex_p'},
|
||||
{name: 'Flying Wing', model: 'custom', image: 'flying_wing'},
|
||||
{name: 'Y4', model: 'y4', image: 'y4'},
|
||||
{name: 'Hex X', model: 'hex_x', image: 'hex_x'},
|
||||
{name: 'Octo X8', model: 'custom', image: 'octo_x8'},
|
||||
{name: 'Octo Flat +', model: 'custom', image: 'octo_flat_p'},
|
||||
{name: 'Octo Flat X', model: 'custom', image: 'octo_flat_x'},
|
||||
{name: 'Airplane', model: 'custom', image: 'airplane'},
|
||||
{name: 'Heli 120', model: 'custom', image: 'custom'},
|
||||
{name: 'Heli 90', model: 'custom', image: 'custom'},
|
||||
{name: 'V-tail Quad', model: 'quad_vtail', image: 'vtail_quad'},
|
||||
{name: 'Hex H', model: 'custom', image: 'custom'},
|
||||
{name: 'PPM to SERVO', model: 'custom', image: 'custom'},
|
||||
{name: 'Dualcopter', model: 'custom', image: 'custom'},
|
||||
{name: 'Singlecopter', model: 'custom', image: 'custom'},
|
||||
{name: 'A-tail Quad', model: 'quad_atail', image: 'atail_quad'},
|
||||
{name: 'Custom', model: 'custom', image: 'custom'},
|
||||
{name: 'Custom Airplane', model: 'custom', image: 'custom'},
|
||||
{name: 'Custom Tricopter', model: 'custom', image: 'custom'}
|
||||
|
||||
{name: 'Tricopter', model: 'tricopter', image: 'tri'}, // 1
|
||||
{name: 'Quad +', model: 'quad_x', image: 'quad_p'}, // 2
|
||||
{name: 'Quad X', model: 'quad_x', image: 'quad_x'}, // 3
|
||||
{name: 'Bicopter', model: 'custom', image: 'bicopter'}, // 4
|
||||
{name: 'Gimbal', model: 'custom', image: 'custom'}, // 5
|
||||
{name: 'Y6', model: 'y6', image: 'y6'}, // 6
|
||||
{name: 'Hex +', model: 'hex_plus', image: 'hex_p'}, // 7
|
||||
{name: 'Flying Wing', model: 'custom', image: 'flying_wing'}, // 8
|
||||
{name: 'Y4', model: 'y4', image: 'y4'}, // 9
|
||||
{name: 'Hex X', model: 'hex_x', image: 'hex_x'}, // 10
|
||||
{name: 'Octo X8', model: 'custom', image: 'octo_x8'}, // 11
|
||||
{name: 'Octo Flat +', model: 'custom', image: 'octo_flat_p'}, // 12
|
||||
{name: 'Octo Flat X', model: 'custom', image: 'octo_flat_x'}, // 13
|
||||
{name: 'Airplane', model: 'custom', image: 'airplane'}, // 14
|
||||
{name: 'Heli 120', model: 'custom', image: 'custom'}, // 15
|
||||
{name: 'Heli 90', model: 'custom', image: 'custom'}, // 16
|
||||
{name: 'V-tail Quad', model: 'quad_vtail', image: 'vtail_quad'}, // 17
|
||||
{name: 'Hex H', model: 'custom', image: 'custom'}, // 18
|
||||
{name: 'PPM to SERVO', model: 'custom', image: 'custom'}, // 19
|
||||
{name: 'Dualcopter', model: 'custom', image: 'custom'}, // 20
|
||||
{name: 'Singlecopter', model: 'custom', image: 'custom'}, // 21
|
||||
{name: 'A-tail Quad', model: 'quad_atail', image: 'atail_quad'}, // 22
|
||||
{name: 'Custom', model: 'custom', image: 'custom'}, // 23
|
||||
{name: 'Custom Airplane', model: 'custom', image: 'custom'}, // 24
|
||||
{name: 'Custom Tricopter', model: 'custom', image: 'custom'} // 25
|
||||
];
|
||||
|
|
|
@ -824,14 +824,14 @@ var mspHelper = (function (gui) {
|
|||
FILTER_CONFIG.gyroSoftLpfHz = data.getUint8(0);
|
||||
FILTER_CONFIG.dtermLpfHz = data.getUint16(1, true);
|
||||
FILTER_CONFIG.yawLpfHz = data.getUint16(3, true);
|
||||
/*
|
||||
sbufWriteU16(dst, 1); //masterConfig.gyro_soft_notch_hz_1
|
||||
sbufWriteU16(dst, 1); //BF: masterConfig.gyro_soft_notch_cutoff_1
|
||||
sbufWriteU16(dst, 1); //BF: currentProfile->pidProfile.dterm_notch_hz
|
||||
sbufWriteU16(dst, 1); //currentProfile->pidProfile.dterm_notch_cutoff
|
||||
sbufWriteU16(dst, 1); //BF: masterConfig.gyro_soft_notch_hz_2
|
||||
sbufWriteU16(dst, 1); //BF: masterConfig.gyro_soft_notch_cutoff_2
|
||||
*/
|
||||
|
||||
FILTER_CONFIG.gyroNotchHz1 = data.getUint16(5, true);
|
||||
FILTER_CONFIG.gyroNotchCutoff1 = data.getUint16(7, true);
|
||||
FILTER_CONFIG.dtermNotchHz = data.getUint16(9, true);
|
||||
FILTER_CONFIG.dtermNotchCutoff = data.getUint16(11, true);
|
||||
FILTER_CONFIG.gyroNotchHz2 = data.getUint16(13, true);
|
||||
FILTER_CONFIG.gyroNotchCutoff2 = data.getUint16(15, true);
|
||||
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SET_FILTER_CONFIG:
|
||||
|
@ -1230,23 +1230,23 @@ var mspHelper = (function (gui) {
|
|||
buffer.push(lowByte(FILTER_CONFIG.yawLpfHz));
|
||||
buffer.push(highByte(FILTER_CONFIG.yawLpfHz));
|
||||
|
||||
buffer.push(0);
|
||||
buffer.push(0);
|
||||
buffer.push(lowByte(FILTER_CONFIG.gyroNotchHz1));
|
||||
buffer.push(highByte(FILTER_CONFIG.gyroNotchHz1));
|
||||
|
||||
buffer.push(0);
|
||||
buffer.push(0);
|
||||
buffer.push(lowByte(FILTER_CONFIG.gyroNotchCutoff1));
|
||||
buffer.push(highByte(FILTER_CONFIG.gyroNotchCutoff1));
|
||||
|
||||
buffer.push(0);
|
||||
buffer.push(0);
|
||||
buffer.push(lowByte(FILTER_CONFIG.dtermNotchHz));
|
||||
buffer.push(highByte(FILTER_CONFIG.dtermNotchHz));
|
||||
|
||||
buffer.push(0);
|
||||
buffer.push(0);
|
||||
buffer.push(lowByte(FILTER_CONFIG.dtermNotchCutoff));
|
||||
buffer.push(highByte(FILTER_CONFIG.dtermNotchCutoff));
|
||||
|
||||
buffer.push(0);
|
||||
buffer.push(0);
|
||||
buffer.push(lowByte(FILTER_CONFIG.gyroNotchHz2));
|
||||
buffer.push(highByte(FILTER_CONFIG.gyroNotchHz2));
|
||||
|
||||
buffer.push(0);
|
||||
buffer.push(0);
|
||||
buffer.push(lowByte(FILTER_CONFIG.gyroNotchCutoff2));
|
||||
buffer.push(highByte(FILTER_CONFIG.gyroNotchCutoff2));
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SET_PID_ADVANCED:
|
||||
|
@ -1715,5 +1715,208 @@ var mspHelper = (function (gui) {
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Basic sending methods used for chaining purposes
|
||||
*/
|
||||
self.loadMspIdent = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadINAVPidConfig = function(callback) {
|
||||
if (semver.gt(CONFIG.flightControllerVersion, "1.3.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_INAV_PID, false, false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.loadLoopTime = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_LOOP_TIME, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadAdvancedConfig = function(callback) {
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.3.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.loadFilterConfig = function (callback) {
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.4.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_FILTER_CONFIG, false, false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.loadPidAdvanced = function (callback) {
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.4.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_PID_ADVANCED, false, false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.loadRcTuningData = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_RC_TUNING, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadPidData = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_PID, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadPidNames = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_PIDNAMES, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadStatus = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadBfConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadMisc = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_MISC, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadArmingConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_ARMING_CONFIG, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadRxConfig = function (callback) {
|
||||
if (semver.gte(CONFIG.apiVersion, "1.21.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_RX_CONFIG, false, false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.load3dConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_3D, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadSensorAlignment = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_ALIGNMENT, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadSensorConfig = function (callback) {
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_CONFIG, false, false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.loadRcDeadband = function (callback) {
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_RC_DEADBAND, false, false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.loadRcMap = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_RX_MAP, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadRcData = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_RC, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadAccTrim = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_ACC_TRIM, false, false, callback);
|
||||
};
|
||||
|
||||
self.saveToEeprom = function saveToEeprom(callback) {
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, callback);
|
||||
};
|
||||
|
||||
self.saveINAVPidConfig = function (callback) {
|
||||
if (semver.gt(CONFIG.flightControllerVersion, "1.3.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_INAV_PID, mspHelper.crunch(MSPCodes.MSP_SET_INAV_PID), false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.saveLooptimeConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_LOOP_TIME, mspHelper.crunch(MSPCodes.MSP_SET_LOOP_TIME), false, callback);
|
||||
};
|
||||
|
||||
self.saveAdvancedConfig = function (callback) {
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.3.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_ADVANCED_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ADVANCED_CONFIG), false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.saveFilterConfig = function (callback) {
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.4.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_FILTER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FILTER_CONFIG), false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.savePidData = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_PID, mspHelper.crunch(MSPCodes.MSP_SET_PID), false, callback);
|
||||
};
|
||||
|
||||
self.saveRcTuningData = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_RC_TUNING, mspHelper.crunch(MSPCodes.MSP_SET_RC_TUNING), false, callback);
|
||||
};
|
||||
|
||||
self.savePidAdvanced = function (callback) {
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.4.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_PID_ADVANCED, mspHelper.crunch(MSPCodes.MSP_SET_PID_ADVANCED), false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.saveBfConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_BF_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_BF_CONFIG), false, callback);
|
||||
};
|
||||
|
||||
self.saveMisc = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_MISC, mspHelper.crunch(MSPCodes.MSP_SET_MISC), false, callback);
|
||||
};
|
||||
|
||||
self.save3dConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_3D, mspHelper.crunch(MSPCodes.MSP_SET_3D), false, callback);
|
||||
};
|
||||
|
||||
self.saveSensorAlignment = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_SENSOR_ALIGNMENT, mspHelper.crunch(MSPCodes.MSP_SET_SENSOR_ALIGNMENT), false, callback);
|
||||
};
|
||||
|
||||
self.saveAccTrim = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_ACC_TRIM, mspHelper.crunch(MSPCodes.MSP_SET_ACC_TRIM), false, callback);
|
||||
};
|
||||
|
||||
self.saveArmingConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_ARMING_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ARMING_CONFIG), false, callback);
|
||||
};
|
||||
|
||||
self.saveRxConfig = function (callback) {
|
||||
if(semver.gte(CONFIG.apiVersion, "1.21.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_RX_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_RX_CONFIG), false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.saveSensorConfig = function (callback) {
|
||||
if(semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_SENSOR_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_SENSOR_CONFIG), false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
return self;
|
||||
})(GUI);
|
||||
|
|
35
js/msp/MSPchainer.js
Normal file
35
js/msp/MSPchainer.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*global $*/
|
||||
'use strict';
|
||||
|
||||
var MSPChainerClass = function () {
|
||||
|
||||
var self = {};
|
||||
|
||||
self.chain = [];
|
||||
self.exitPoint = null;
|
||||
self.chainIndex = 0;
|
||||
|
||||
self.setChain = function(chain) {
|
||||
self.chain = chain;
|
||||
};
|
||||
|
||||
self.setExitPoint = function (exitPoint) {
|
||||
self.exitPoint = exitPoint;
|
||||
};
|
||||
|
||||
self.returnCallback = function () {
|
||||
self.chainIndex++;
|
||||
if (self.chain[self.chainIndex]) {
|
||||
self.chain[self.chainIndex](self.returnCallback);
|
||||
} else {
|
||||
self.exitPoint();
|
||||
}
|
||||
};
|
||||
|
||||
self.execute = function() {
|
||||
self.chainIndex = 0;
|
||||
self.chain[self.chainIndex](self.returnCallback);
|
||||
};
|
||||
|
||||
return self;
|
||||
};
|
|
@ -260,6 +260,13 @@ function onOpen(openInfo) {
|
|||
GUI.allowedTabs.splice(GUI.allowedTabs.indexOf('osd'), 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove Presets on older than 1.6
|
||||
*/
|
||||
if (semver.lt(CONFIG.flightControllerVersion, "1.6.0")) {
|
||||
GUI.allowedTabs.splice(GUI.allowedTabs.indexOf('profiles'), 1);
|
||||
}
|
||||
|
||||
onConnect();
|
||||
|
||||
$('#tabs ul.mode-connected .tab_setup a').click();
|
||||
|
|
79
main.css
79
main.css
|
@ -1819,4 +1819,83 @@ select {
|
|||
|
||||
.full-width {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modal__content {
|
||||
|
||||
}
|
||||
|
||||
.modal__buttons {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.modal__button {
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #37a8db;
|
||||
color: #37a8db;
|
||||
font-family: 'open_sanssemibold', Arial, serif;
|
||||
font-size: 12px;
|
||||
line-height: 13px;
|
||||
display: block;
|
||||
transition: all ease 0.2s;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal__button--main {
|
||||
background-color: #37a8db;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.25);
|
||||
color: #fff;
|
||||
border: 1px solid #3a9dbf;
|
||||
transition: all ease 0.2s;
|
||||
}
|
||||
|
||||
.modal__button--main:active {
|
||||
background-color: #37a8db;
|
||||
transition: all ease 0.0s;
|
||||
box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.modal__button--main:hover {
|
||||
background-color: #3394b5;
|
||||
transition: all ease 0.2s;
|
||||
}
|
||||
|
||||
.modal__button--disabled {
|
||||
cursor: default;
|
||||
color: #fff;
|
||||
background-color: #AFAFAF;
|
||||
border: 1px solid #AFAFAF;
|
||||
pointer-events: none;
|
||||
text-shadow: none;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.modal__title {
|
||||
border-bottom: 1px solid #37a8db;
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
height: 30px;
|
||||
font-family: 'open_sanslight', Arial, serif;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.modal__title--warning {
|
||||
border-bottom: none;
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
.modal__text {
|
||||
line-height: 1.5em;
|
||||
font-size: 1.3em;
|
||||
}
|
13
main.html
13
main.html
|
@ -28,6 +28,7 @@
|
|||
<link type="text/css" rel="stylesheet" href="./tabs/failsafe.css" media="all" />
|
||||
<link type="text/css" rel="stylesheet" href="./tabs/transponder.css" media="all" />
|
||||
<link type="text/css" rel="stylesheet" href="./tabs/osd.css" media="all" />
|
||||
<link type="text/css" rel="stylesheet" href="./tabs/profiles.css" media="all" />
|
||||
<link type="text/css" rel="stylesheet" href="./css/opensans_webfontkit/fonts.css" media="all" />
|
||||
<link type="text/css" rel="stylesheet" href="./css/dropdown-lists/css/style_lists.css" media="all" />
|
||||
<link type="text/css" rel="stylesheet" href="./js/libraries/switchery/switchery.css" media="all" />
|
||||
|
@ -52,6 +53,7 @@
|
|||
<script type="text/javascript" src="./js/gui.js"></script>
|
||||
<script type="text/javascript" src="./js/msp/MSPCodes.js"></script>
|
||||
<script type="text/javascript" src="./js/msp/MSPHelper.js"></script>
|
||||
<script type="text/javascript" src="./js/msp/MSPChainer.js"></script>
|
||||
<script type="text/javascript" src="./js/port_handler.js"></script>
|
||||
<script type="text/javascript" src="./js/port_usage.js"></script>
|
||||
<script type="text/javascript" src="./js/serial.js"></script>
|
||||
|
@ -87,6 +89,7 @@
|
|||
<script type="text/javascript" src="./tabs/failsafe.js"></script>
|
||||
<script type="text/javascript" src="./tabs/transponder.js"></script>
|
||||
<script type="text/javascript" src="./tabs/osd.js"></script>
|
||||
<script type="text/javascript" src="./tabs/profiles.js"></script>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -220,6 +223,7 @@
|
|||
</ul>
|
||||
<ul class="mode-connected">
|
||||
<li class="tab_setup"><a href="#" data-i18n="tabSetup" class="tabicon ic_setup" title="Setup"></a></li>
|
||||
<li class="tab_profiles"><a href="#" data-i18n="tabPresets" class="tabicon ic_wizzard" title="Presets"></a></li>
|
||||
<li class="tab_ports"><a href="#" data-i18n="tabPorts" class="tabicon ic_ports" title="Ports"></a></li>
|
||||
<li class="tab_configuration"><a href="#" data-i18n="tabConfiguration" class="tabicon ic_config" title="Configuration"></a></li>
|
||||
<li class="tab_failsafe"><a href="#" data-i18n="tabFailsafe" class="tabicon ic_failsafe" title="Failsafe"></a></li>
|
||||
|
@ -237,11 +241,10 @@
|
|||
<li class="tab_logging"><a href="#" data-i18n="tabLogging" class="tabicon ic_log" title="Tethered Logging"></a></li>
|
||||
<li class="tab_onboard_logging"><a href="#" data-i18n="tabOnboardLogging" class="tabicon ic_data" title="Onboard Logging"></a></li>
|
||||
<li class="tab_cli"><a href="#" data-i18n="tabCLI" class="tabicon ic_cli" title="CLI"></a></li>
|
||||
<!-- spare icons
|
||||
<li class=""><a href="#"class="tabicon ic_mission">Mission (spare icon)</a></li>
|
||||
<li class=""><a href="#"class="tabicon ic_advanced">Advanced (spare icon)</a></li>
|
||||
<li class=""><a href="#"class="tabicon ic_wizzard">Wizzard (spare icon)</a></li>
|
||||
-->
|
||||
|
||||
<!--<li class=""><a href="#" class="tabicon ic_mission">Mission (spare icon)</a></li>-->
|
||||
<!--<li class=""><a href="#" class="tabicon ic_advanced">Advanced (spare icon)</a></li>-->
|
||||
<!--<li class=""><a href="#" class="tabicon ic_wizzard">Wizzard (spare icon)</a></li>-->
|
||||
</ul>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
|
|
3
main.js
3
main.js
|
@ -148,6 +148,9 @@ $(document).ready(function () {
|
|||
case 'configuration':
|
||||
TABS.configuration.initialize(content_ready);
|
||||
break;
|
||||
case 'profiles':
|
||||
TABS.profiles.initialize(content_ready);
|
||||
break;
|
||||
case 'pid_tuning':
|
||||
TABS.pid_tuning.initialize(content_ready);
|
||||
break;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/*global chrome*/
|
||||
'use strict';
|
||||
|
||||
TABS.configuration = {};
|
||||
|
@ -9,80 +10,62 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
googleAnalytics.sendAppView('Configuration');
|
||||
}
|
||||
|
||||
function load_config() {
|
||||
MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, load_misc);
|
||||
}
|
||||
var loadChainer = new MSPChainerClass();
|
||||
|
||||
function load_misc() {
|
||||
MSP.send_message(MSPCodes.MSP_MISC, false, false, load_arming_config);
|
||||
}
|
||||
loadChainer.setChain([
|
||||
mspHelper.loadMspIdent,
|
||||
mspHelper.loadBfConfig,
|
||||
mspHelper.loadMisc,
|
||||
mspHelper.loadArmingConfig,
|
||||
mspHelper.loadLoopTime,
|
||||
mspHelper.loadRxConfig,
|
||||
mspHelper.load3dConfig,
|
||||
mspHelper.loadSensorAlignment,
|
||||
mspHelper.loadAdvancedConfig,
|
||||
mspHelper.loadINAVPidConfig,
|
||||
mspHelper.loadSensorConfig,
|
||||
mspHelper.loadAccTrim
|
||||
]);
|
||||
loadChainer.setExitPoint(load_html);
|
||||
loadChainer.execute();
|
||||
|
||||
function load_arming_config() {
|
||||
MSP.send_message(MSPCodes.MSP_ARMING_CONFIG, false, false, load_loop_time);
|
||||
}
|
||||
var saveChainer = new MSPChainerClass();
|
||||
|
||||
function load_loop_time() {
|
||||
MSP.send_message(MSPCodes.MSP_LOOP_TIME, false, false, load_rx_config);
|
||||
}
|
||||
saveChainer.setChain([
|
||||
mspHelper.saveBfConfig,
|
||||
mspHelper.saveMisc,
|
||||
mspHelper.save3dConfig,
|
||||
mspHelper.saveSensorAlignment,
|
||||
mspHelper.saveAccTrim,
|
||||
mspHelper.saveArmingConfig,
|
||||
mspHelper.saveLooptimeConfig,
|
||||
mspHelper.saveRxConfig,
|
||||
mspHelper.saveAdvancedConfig,
|
||||
mspHelper.saveINAVPidConfig,
|
||||
mspHelper.saveSensorConfig,
|
||||
mspHelper.saveToEeprom
|
||||
]);
|
||||
saveChainer.setExitPoint(reboot);
|
||||
|
||||
function load_rx_config() {
|
||||
var next_callback = load_3d;
|
||||
if (semver.gte(CONFIG.apiVersion, "1.21.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_RX_CONFIG, false, false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
function reboot() {
|
||||
//noinspection JSUnresolvedVariable
|
||||
GUI.log(chrome.i18n.getMessage('configurationEepromSaved'));
|
||||
|
||||
function load_3d() {
|
||||
MSP.send_message(MSPCodes.MSP_3D, false, false, load_sensor_alignment);
|
||||
}
|
||||
|
||||
function load_sensor_alignment() {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_ALIGNMENT, false, false, loadAdvancedConfig);
|
||||
}
|
||||
|
||||
function loadAdvancedConfig() {
|
||||
var next_callback = loadINAVPidConfig;
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.3.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function loadINAVPidConfig() {
|
||||
var next_callback = loadSensorConfig;
|
||||
if (semver.gt(CONFIG.flightControllerVersion, "1.3.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_INAV_PID, false, false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function loadSensorConfig() {
|
||||
var next_callback = load_html;
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_CONFIG, false, false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
//Update Analog/Battery Data
|
||||
function load_analog() {
|
||||
MSP.send_message(MSPCodes.MSP_ANALOG, false, false, function () {
|
||||
$('#batteryvoltage').val([ANALOG.voltage.toFixed(1)]);
|
||||
$('#batterycurrent').val([ANALOG.amperage.toFixed(2)]);
|
||||
GUI.tab_switch_cleanup(function() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, reinitialize);
|
||||
});
|
||||
}
|
||||
|
||||
function reinitialize() {
|
||||
//noinspection JSUnresolvedVariable
|
||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||
GUI.handleReconnect($('.tab_configuration a'));
|
||||
}
|
||||
|
||||
function load_html() {
|
||||
$('#content').load("./tabs/configuration.html", process_html);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, load_config);
|
||||
|
||||
function process_html() {
|
||||
|
||||
var i;
|
||||
|
@ -646,86 +629,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
}
|
||||
}
|
||||
|
||||
function save_misc() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_MISC, mspHelper.crunch(MSPCodes.MSP_SET_MISC), false, save_3d);
|
||||
}
|
||||
|
||||
function save_3d() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_3D, mspHelper.crunch(MSPCodes.MSP_SET_3D), false, save_sensor_alignment);
|
||||
}
|
||||
|
||||
function save_sensor_alignment() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_SENSOR_ALIGNMENT, mspHelper.crunch(MSPCodes.MSP_SET_SENSOR_ALIGNMENT), false, save_acc_trim);
|
||||
}
|
||||
|
||||
function save_acc_trim() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_ACC_TRIM, mspHelper.crunch(MSPCodes.MSP_SET_ACC_TRIM), false, save_arming_config);
|
||||
}
|
||||
|
||||
function save_arming_config() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_ARMING_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ARMING_CONFIG), false, save_looptime_config);
|
||||
}
|
||||
|
||||
function save_looptime_config() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_LOOP_TIME, mspHelper.crunch(MSPCodes.MSP_SET_LOOP_TIME), false, save_rx_config);
|
||||
}
|
||||
|
||||
function save_rx_config() {
|
||||
var next_callback = saveAdvancedConfig;
|
||||
if(semver.gte(CONFIG.apiVersion, "1.21.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_RX_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_RX_CONFIG), false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function saveAdvancedConfig() {
|
||||
var next_callback = saveINAVPidConfig;
|
||||
if(semver.gte(CONFIG.flightControllerVersion, "1.3.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_ADVANCED_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ADVANCED_CONFIG), false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function saveINAVPidConfig() {
|
||||
var next_callback = saveSensorConfig;
|
||||
if(semver.gt(CONFIG.flightControllerVersion, "1.3.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_INAV_PID, mspHelper.crunch(MSPCodes.MSP_SET_INAV_PID), false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function saveSensorConfig() {
|
||||
var next_callback = save_to_eeprom;
|
||||
if(semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_SENSOR_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_SENSOR_CONFIG), false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function save_to_eeprom() {
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, reboot);
|
||||
}
|
||||
|
||||
function reboot() {
|
||||
//noinspection JSUnresolvedVariable
|
||||
GUI.log(chrome.i18n.getMessage('configurationEepromSaved'));
|
||||
|
||||
GUI.tab_switch_cleanup(function() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, reinitialize);
|
||||
});
|
||||
}
|
||||
|
||||
function reinitialize() {
|
||||
//noinspection JSUnresolvedVariable
|
||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||
GUI.handleReconnect($('.tab_configuration a'));
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_SET_BF_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_BF_CONFIG), false, save_misc);
|
||||
saveChainer.execute();
|
||||
});
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
|
@ -736,7 +640,12 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
GUI.interval_add('config_load_analog', load_analog, 250, true); // 4 fps
|
||||
GUI.interval_add('config_load_analog', function () {
|
||||
MSP.send_message(MSPCodes.MSP_ANALOG, false, false, function () {
|
||||
$('#batteryvoltage').val([ANALOG.voltage.toFixed(1)]);
|
||||
$('#batterycurrent').val([ANALOG.amperage.toFixed(2)]);
|
||||
});
|
||||
}, 250, true); // 4 fps
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/*global chrome*/
|
||||
'use strict';
|
||||
|
||||
TABS.pid_tuning = {
|
||||
|
@ -5,60 +6,30 @@ TABS.pid_tuning = {
|
|||
};
|
||||
|
||||
TABS.pid_tuning.initialize = function (callback) {
|
||||
var self = this;
|
||||
|
||||
var loadChainer = new MSPChainerClass();
|
||||
|
||||
loadChainer.setChain([
|
||||
mspHelper.loadStatus,
|
||||
mspHelper.loadPidNames,
|
||||
mspHelper.loadPidData,
|
||||
mspHelper.loadRcTuningData,
|
||||
mspHelper.loadINAVPidConfig,
|
||||
mspHelper.loadPidAdvanced,
|
||||
mspHelper.loadFilterConfig
|
||||
]);
|
||||
loadChainer.setExitPoint(load_html);
|
||||
loadChainer.execute();
|
||||
|
||||
if (GUI.active_tab != 'pid_tuning') {
|
||||
GUI.active_tab = 'pid_tuning';
|
||||
googleAnalytics.sendAppView('PID Tuning');
|
||||
}
|
||||
|
||||
function get_pid_names() {
|
||||
MSP.send_message(MSPCodes.MSP_PIDNAMES, false, false, get_pid_data);
|
||||
}
|
||||
|
||||
function get_pid_data() {
|
||||
MSP.send_message(MSPCodes.MSP_PID, false, false, get_rc_tuning_data);
|
||||
}
|
||||
|
||||
function get_rc_tuning_data() {
|
||||
MSP.send_message(MSPCodes.MSP_RC_TUNING, false, false, loadINAVPidConfig);
|
||||
}
|
||||
|
||||
function loadINAVPidConfig() {
|
||||
var next_callback = loadPidAdvanced;
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.4.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_INAV_PID, false, false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function loadPidAdvanced() {
|
||||
var next_callback = loadFilterConfig;
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.4.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_PID_ADVANCED, false, false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function loadFilterConfig() {
|
||||
var next_callback = load_html;
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.4.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_FILTER_CONFIG, false, false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function load_html() {
|
||||
$('#content').load("./tabs/pid_tuning.html", process_html);
|
||||
}
|
||||
|
||||
// requesting MSP_STATUS manually because it contains CONFIG.profile
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false, get_pid_names);
|
||||
|
||||
var sectionClasses = [
|
||||
'ROLL', // 0
|
||||
'PITCH', // 1
|
||||
|
@ -181,8 +152,6 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
|
||||
pid_and_rc_to_form();
|
||||
|
||||
var form_e = $('#pid-tuning');
|
||||
|
||||
if (FC.isRatesInDps()) {
|
||||
$('.rate-tpa--no-dps').hide();
|
||||
} else {
|
||||
|
|
27
tabs/profiles.css
Normal file
27
tabs/profiles.css
Normal file
|
@ -0,0 +1,27 @@
|
|||
#presets-list option {
|
||||
padding: 0.4em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.preset__head {
|
||||
color: #37a8db;
|
||||
}
|
||||
|
||||
.preset__description {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.preset__features {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.preset__feature {
|
||||
list-style: disc;
|
||||
color: #37a8db;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
.preset__feature-text {
|
||||
color: #000000;
|
||||
margin-left: -0.5em;
|
||||
}
|
52
tabs/profiles.html
Normal file
52
tabs/profiles.html
Normal file
|
@ -0,0 +1,52 @@
|
|||
<div class="tab-configuration tab-profiles toolbar_fixed_bottom">
|
||||
<div class="content_wrapper">
|
||||
<div class="tab_title" data-i18n="tabPresets">Presets</div>
|
||||
|
||||
<div class="cf_column third_left">
|
||||
<div class="spacer_right">
|
||||
<div class="gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="presetsPreset"></div>
|
||||
</div>
|
||||
<div class="spacer_box">
|
||||
<div class="select">
|
||||
<select id="presets-list" class="full-width" size="8">
|
||||
<!-- list generated here -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cf_column twothird">
|
||||
<div class="gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="presetsDescription"></div>
|
||||
</div>
|
||||
<div class="spacer_box preset">
|
||||
<h2 id="preset-name" class="preset__head"></h2>
|
||||
<p id="preset-description" class="preset__description"></p>
|
||||
<ul id="preset-features" class="preset__features"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="presetApplyContent" class="is-hidden">
|
||||
<div class="modal__content">
|
||||
<h1 class="modal__title modal__title--warning" data-i18n="presetsApplyHeader"></h1>
|
||||
<div class="modal__text" data-i18n="presetApplyDescription"></div>
|
||||
</div>
|
||||
<div class="modal__buttons">
|
||||
<a id="execute-button" class="modal__button modal__button--main" data-i18n="presetsButtonSaveAndReboot"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
<div class="content_toolbar">
|
||||
<div class="btn save_btn">
|
||||
<a id="save-button" class="save disabled" href="#" data-i18n="presetsButtonApply"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
384
tabs/profiles.js
Normal file
384
tabs/profiles.js
Normal file
|
@ -0,0 +1,384 @@
|
|||
'use strict';
|
||||
|
||||
var presets = presets || {};
|
||||
|
||||
presets.elementHelper = function (group, field, value) {
|
||||
return {
|
||||
group: group,
|
||||
field: field,
|
||||
value: value
|
||||
}
|
||||
};
|
||||
|
||||
presets.defaultValues = {
|
||||
PIDs: [
|
||||
[40, 30, 23],
|
||||
[40, 30, 23],
|
||||
[85, 45, 0],
|
||||
[50, 0, 0],
|
||||
[65, 120, 10],
|
||||
[180, 15, 100],
|
||||
[10, 5, 8],
|
||||
[20, 15, 75],
|
||||
[60, 0, 0],
|
||||
[100, 50, 10]
|
||||
],
|
||||
INAV_PID_CONFIG: {"asynchronousMode": "0", "accelerometerTaskFrequency": 500, "attitudeTaskFrequency": 250, "magHoldRateLimit": 90, "magHoldErrorLpfFrequency": 2, "yawJumpPreventionLimit": 200, "gyroscopeLpf": "3", "accSoftLpfHz": 15},
|
||||
ADVANCED_CONFIG: {"gyroSyncDenominator": 2, "pidProcessDenom": 1, "useUnsyncedPwm": 1, "motorPwmProtocol": 0, "motorPwmRate": 400, "servoPwmRate": 50, "gyroSync": 0},
|
||||
RC_tuning: {"RC_RATE": 0, "RC_EXPO": 0, "roll_pitch_rate": 0, "roll_rate": 0, "pitch_rate": 0, "yaw_rate": 0, "dynamic_THR_PID": 0, "throttle_MID": 0, "throttle_EXPO": 0, "dynamic_THR_breakpoint": 0, "RC_YAW_EXPO": 0},
|
||||
PID_ADVANCED: {"rollPitchItermIgnoreRate": 200, "yawItermIgnoreRate": 50, "yawPLimit": 300, "axisAccelerationLimitRollPitch": 0, "axisAccelerationLimitYaw": 1000},
|
||||
FILTER_CONFIG: {"gyroSoftLpfHz": 60, "dtermLpfHz": 40, "yawLpfHz": 30, "gyroNotchHz1": 0, "gyroNotchCutoff1": 0, "dtermNotchHz": 0, "dtermNotchCutoff": 0, "gyroNotchHz2": 0, "gyroNotchCutoff2": 0},
|
||||
FC_CONFIG: {"loopTime": 2000}
|
||||
};
|
||||
|
||||
/*
|
||||
* When defining a preset, following fields are required:
|
||||
*
|
||||
* BF_CONFIG::mixerConfiguration
|
||||
*
|
||||
*/
|
||||
presets.presets = [
|
||||
{
|
||||
name: 'Default Preset',
|
||||
description: "INAV default Quad X configuration",
|
||||
features: [],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
presets.elementHelper("BF_CONFIG", "mixerConfiguration", 3)
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '5" Racer',
|
||||
description: "210-250 class racer with F3/F4 CPU on 4S battery",
|
||||
features: [
|
||||
"4S battery",
|
||||
"2000KV - 2600KV motors",
|
||||
"5 inch propellers",
|
||||
"400g-650g weight",
|
||||
"F3 or F4 CPU",
|
||||
"MPU6000 or MPU6050 gyro",
|
||||
"No GPS capabilities"
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
presets.elementHelper("BF_CONFIG", "mixerConfiguration", 3),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "asynchronousMode", 2),
|
||||
presets.elementHelper("FC_CONFIG", "loopTime", 1000),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "gyroscopeLpf", 0),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "attitudeTaskFrequency", 100),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSync", 1),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSyncDenominator", 4),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "motorPwmProtocol", 1),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "motorPwmRate", 2000),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroSoftLpfHz", 90),
|
||||
presets.elementHelper("FILTER_CONFIG", "dtermLpfHz", 80),
|
||||
presets.elementHelper("RC_tuning", "roll_rate", 800),
|
||||
presets.elementHelper("RC_tuning", "pitch_rate", 800),
|
||||
presets.elementHelper("RC_tuning", "yaw_rate", 650),
|
||||
presets.elementHelper("FILTER_CONFIG", "dtermNotchHz", 260),
|
||||
presets.elementHelper("FILTER_CONFIG", "dtermNotchCutoff", 160),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchHz1", 400),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchCutoff1", 300),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchHz2", 200),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchCutoff2", 100),
|
||||
presets.elementHelper("PIDs", 0, [43, 40, 20]), //ROLL PIDs
|
||||
presets.elementHelper("PIDs", 1, [58, 50, 22]), //PITCH PIDs
|
||||
presets.elementHelper("PIDs", 2, [70, 45, 0]) //YAW PIDs
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '10" General Purpose',
|
||||
description: "450-600 class general purpose multirotor",
|
||||
features: [
|
||||
"10 inch propellers",
|
||||
"0.kg - 1.4kg weight",
|
||||
"F1, F3 or F4 CPU",
|
||||
"MPU6000 or MPU6050 gyro",
|
||||
"GPS optional"
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
presets.elementHelper("BF_CONFIG", "mixerConfiguration", 3),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "asynchronousMode", 1),
|
||||
presets.elementHelper("FC_CONFIG", "loopTime", 2000),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "gyroscopeLpf", 1),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSync", 1),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSyncDenominator", 1),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroSoftLpfHz", 70),
|
||||
presets.elementHelper("FILTER_CONFIG", "dtermLpfHz", 40),
|
||||
presets.elementHelper("RC_tuning", "roll_rate", 400),
|
||||
presets.elementHelper("RC_tuning", "pitch_rate", 400),
|
||||
presets.elementHelper("RC_tuning", "yaw_rate", 200),
|
||||
presets.elementHelper("FILTER_CONFIG", "dtermNotchHz", 125),
|
||||
presets.elementHelper("FILTER_CONFIG", "dtermNotchCutoff", 90),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchHz1", 170),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchCutoff1", 125),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchHz2", 85),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchCutoff2", 43),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "magHoldRateLimit", 30),
|
||||
presets.elementHelper("PID_ADVANCED", "axisAccelerationLimitRollPitch", 40),
|
||||
presets.elementHelper("PID_ADVANCED", "axisAccelerationLimitYaw", 18),
|
||||
presets.elementHelper("PIDs", 0, [75, 30, 18]), //ROLL PIDs
|
||||
presets.elementHelper("PIDs", 1, [75, 30, 18]), //PITCH PIDs
|
||||
presets.elementHelper("PIDs", 2, [85, 45, 0]) //YAW PIDs
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '12" General Purpose',
|
||||
description: "550 and above general purpose multirotor",
|
||||
features: [
|
||||
"12 inch propellers",
|
||||
"1.4kg-2kg weight",
|
||||
"F3 or F4 CPU",
|
||||
"MPU6000 or MPU6050 gyro",
|
||||
"GPS optional"
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
presets.elementHelper("BF_CONFIG", "mixerConfiguration", 3),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "asynchronousMode", 1),
|
||||
presets.elementHelper("FC_CONFIG", "loopTime", 2000),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "gyroscopeLpf", 1),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSync", 1),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSyncDenominator", 1),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroSoftLpfHz", 55),
|
||||
presets.elementHelper("FILTER_CONFIG", "dtermLpfHz", 30),
|
||||
presets.elementHelper("RC_tuning", "roll_rate", 180),
|
||||
presets.elementHelper("RC_tuning", "pitch_rate", 180),
|
||||
presets.elementHelper("RC_tuning", "yaw_rate", 90),
|
||||
presets.elementHelper("FILTER_CONFIG", "dtermNotchHz", 108),
|
||||
presets.elementHelper("FILTER_CONFIG", "dtermNotchCutoff", 72),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchHz1", 144),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchCutoff1", 90),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchHz2", 72),
|
||||
presets.elementHelper("FILTER_CONFIG", "gyroNotchCutoff2", 43),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "magHoldRateLimit", 30),
|
||||
presets.elementHelper("PID_ADVANCED", "axisAccelerationLimitRollPitch", 18),
|
||||
presets.elementHelper("PID_ADVANCED", "axisAccelerationLimitYaw", 9),
|
||||
presets.elementHelper("PIDs", 0, [80, 30, 18]), //ROLL PIDs
|
||||
presets.elementHelper("PIDs", 1, [80, 30, 18]), //PITCH PIDs
|
||||
presets.elementHelper("PIDs", 2, [85, 45, 0]), //YAW PIDs
|
||||
presets.elementHelper("PIDs", 7, [10, 7, 75]) //Level PIDs
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Airplane General",
|
||||
description: "General setup for airplanes",
|
||||
features: [
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
presets.elementHelper("BF_CONFIG", "mixerConfiguration", 14),
|
||||
presets.elementHelper("PIDs", 0, [20, 30, 15]), //ROLL PIDs
|
||||
presets.elementHelper("PIDs", 1, [20, 30, 15]), //PITCH PIDs
|
||||
presets.elementHelper("PIDs", 2, [45, 5, 15]), //YAW PIDs
|
||||
presets.elementHelper("RC_tuning", "roll_rate", 200),
|
||||
presets.elementHelper("RC_tuning", "pitch_rate", 150),
|
||||
presets.elementHelper("RC_tuning", "yaw_rate", 90),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSync", 1),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "gyroscopeLpf", 1)
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "600mm Flying Wing",
|
||||
description: "Small flying wing on multirotor racer parts",
|
||||
features: [
|
||||
"3S-4S battery",
|
||||
"300g-500g weight"
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
presets.elementHelper("BF_CONFIG", "mixerConfiguration", 8),
|
||||
presets.elementHelper("PIDs", 0, [15, 30, 15]), //ROLL PIDs
|
||||
presets.elementHelper("PIDs", 1, [15, 40, 15]), //PITCH PIDs
|
||||
presets.elementHelper("RC_tuning", "roll_rate", 400),
|
||||
presets.elementHelper("RC_tuning", "pitch_rate", 150),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSync", 1),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "gyroscopeLpf", 1)
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
presets.model = (function () {
|
||||
|
||||
var self = {};
|
||||
|
||||
/**
|
||||
* @param {Array} toApply
|
||||
* @param {Object} defaults
|
||||
*/
|
||||
self.applyDefaults = function (toApply, defaults) {
|
||||
|
||||
for (var settingToApply in toApply) {
|
||||
if (toApply.hasOwnProperty(settingToApply)) {
|
||||
|
||||
var settingName = toApply[settingToApply],
|
||||
values = defaults[settingName];
|
||||
|
||||
for (var key in values) {
|
||||
if (values.hasOwnProperty(key)) {
|
||||
window[settingName][key] = values[key];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.extractPresetNames = function(presets) {
|
||||
|
||||
var retVal = {};
|
||||
|
||||
for (var i in presets) {
|
||||
if (presets.hasOwnProperty(i)) {
|
||||
retVal[i] = presets[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
};
|
||||
|
||||
return self;
|
||||
})();
|
||||
|
||||
TABS.profiles = {};
|
||||
|
||||
TABS.profiles.initialize = function (callback, scrollPosition) {
|
||||
|
||||
var currentPreset,
|
||||
currentPresetId,
|
||||
loadChainer = new MSPChainerClass(),
|
||||
saveChainer = new MSPChainerClass();
|
||||
|
||||
if (GUI.active_tab != 'profiles') {
|
||||
GUI.active_tab = 'profiles';
|
||||
googleAnalytics.sendAppView('Presets');
|
||||
}
|
||||
|
||||
loadChainer.setChain([
|
||||
mspHelper.loadMspIdent,
|
||||
mspHelper.loadBfConfig,
|
||||
mspHelper.loadLoopTime,
|
||||
mspHelper.loadINAVPidConfig,
|
||||
mspHelper.loadAdvancedConfig,
|
||||
mspHelper.loadFilterConfig,
|
||||
mspHelper.loadPidAdvanced,
|
||||
mspHelper.loadRcTuningData,
|
||||
mspHelper.loadPidData
|
||||
]);
|
||||
loadChainer.setExitPoint(loadHtml);
|
||||
loadChainer.execute();
|
||||
|
||||
saveChainer.setChain([
|
||||
mspHelper.saveINAVPidConfig,
|
||||
mspHelper.saveLooptimeConfig,
|
||||
mspHelper.saveAdvancedConfig,
|
||||
mspHelper.saveFilterConfig,
|
||||
mspHelper.savePidData,
|
||||
mspHelper.saveRcTuningData,
|
||||
mspHelper.savePidAdvanced,
|
||||
mspHelper.saveBfConfig,
|
||||
mspHelper.saveToEeprom
|
||||
]);
|
||||
saveChainer.setExitPoint(reboot);
|
||||
|
||||
function loadHtml() {
|
||||
$('#content').load("./tabs/profiles.html", processHtml);
|
||||
}
|
||||
|
||||
function reboot() {
|
||||
//noinspection JSUnresolvedVariable
|
||||
GUI.log(chrome.i18n.getMessage('configurationEepromSaved'));
|
||||
GUI.tab_switch_cleanup(function () {
|
||||
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, reinitialize);
|
||||
});
|
||||
}
|
||||
|
||||
function reinitialize() {
|
||||
//noinspection JSUnresolvedVariable
|
||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||
GUI.handleReconnect($('.tab_setup a'));
|
||||
}
|
||||
|
||||
function applyAndSave() {
|
||||
|
||||
presets.model.applyDefaults(currentPreset.applyDefaults, presets.defaultValues);
|
||||
|
||||
var setting;
|
||||
|
||||
//Iterate over settings saved in preset
|
||||
for (var i in currentPreset.settings) {
|
||||
if (currentPreset.settings.hasOwnProperty(i)) {
|
||||
setting = currentPreset.settings[i];
|
||||
//Apply setting
|
||||
window[setting.group][setting.field] = setting.value;
|
||||
}
|
||||
}
|
||||
|
||||
saveChainer.execute();
|
||||
}
|
||||
|
||||
function fillPresetDescription(preset) {
|
||||
|
||||
var $features = $('#preset-features');
|
||||
|
||||
$('#preset-name').html(preset.name);
|
||||
$('#preset-description').html(preset.description);
|
||||
|
||||
$features.find('*').remove();
|
||||
|
||||
for (var i in preset.features) {
|
||||
if (preset.features.hasOwnProperty(i)) {
|
||||
$features.append('<li class="preset__feature"><span class="preset__feature-text">' + preset.features[i] + "</span></li>");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function processHtml() {
|
||||
|
||||
var $presetList = $('#presets-list');
|
||||
|
||||
GUI.fillSelect($presetList, presets.model.extractPresetNames(presets.presets));
|
||||
|
||||
$presetList.change(function () {
|
||||
currentPresetId = $presetList.val();
|
||||
currentPreset = presets.presets[currentPresetId];
|
||||
fillPresetDescription(currentPreset);
|
||||
$('#save-button').removeClass('disabled');
|
||||
});
|
||||
|
||||
$('#execute-button').click(function () {
|
||||
applyAndSave();
|
||||
OSD.GUI.jbox.close();
|
||||
});
|
||||
|
||||
localize();
|
||||
|
||||
//noinspection JSValidateTypes
|
||||
$('#content').scrollTop((scrollPosition) ? scrollPosition : 0);
|
||||
|
||||
OSD.GUI.jbox = new jBox('Modal', {
|
||||
width: 600,
|
||||
height: 240,
|
||||
closeButton: 'title',
|
||||
animation: false,
|
||||
attach: $('#save-button'),
|
||||
title: chrome.i18n.getMessage("presetApplyTitle"),
|
||||
content: $('#presetApplyContent')
|
||||
});
|
||||
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
};
|
||||
|
||||
TABS.profiles.cleanup = function (callback) {
|
||||
if (callback) callback();
|
||||
};
|
|
@ -1,3 +1,5 @@
|
|||
/*global chrome*/
|
||||
|
||||
'use strict';
|
||||
|
||||
TABS.receiver = {
|
||||
|
@ -12,38 +14,23 @@ TABS.receiver.initialize = function (callback) {
|
|||
googleAnalytics.sendAppView('Receiver');
|
||||
}
|
||||
|
||||
function get_misc_data() {
|
||||
MSP.send_message(MSPCodes.MSP_MISC, false, false, get_rc_data);
|
||||
}
|
||||
var loadChainer = new MSPChainerClass();
|
||||
|
||||
function get_rc_data() {
|
||||
MSP.send_message(MSPCodes.MSP_RC, false, false, get_rc_map);
|
||||
}
|
||||
|
||||
function get_rc_map() {
|
||||
MSP.send_message(MSPCodes.MSP_RX_MAP, false, false, load_config);
|
||||
}
|
||||
|
||||
// Fetch features so we can check if RX_MSP is enabled:
|
||||
function load_config() {
|
||||
MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, load_rc_configs);
|
||||
}
|
||||
|
||||
function load_rc_configs() {
|
||||
var next_callback = load_html;
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_RC_DEADBAND, false, false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
}
|
||||
loadChainer.setChain([
|
||||
mspHelper.loadRcTuningData,
|
||||
mspHelper.loadMisc,
|
||||
mspHelper.loadRcData,
|
||||
mspHelper.loadRcMap,
|
||||
mspHelper.loadBfConfig,
|
||||
mspHelper.loadRcDeadband
|
||||
]);
|
||||
loadChainer.setExitPoint(load_html);
|
||||
loadChainer.execute();
|
||||
|
||||
function load_html() {
|
||||
$('#content').load("./tabs/receiver.html", process_html);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_RC_TUNING, false, false, get_misc_data);
|
||||
|
||||
function process_html() {
|
||||
// translate to user-selected language
|
||||
localize();
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/*global chrome*/
|
||||
'use strict';
|
||||
|
||||
TABS.setup = {
|
||||
|
@ -12,24 +13,21 @@ TABS.setup.initialize = function (callback) {
|
|||
googleAnalytics.sendAppView('Setup');
|
||||
}
|
||||
|
||||
function load_ident() {
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, load_config);
|
||||
}
|
||||
var loadChainer = new MSPChainerClass();
|
||||
|
||||
function load_config() {
|
||||
MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, load_misc_data);
|
||||
}
|
||||
|
||||
function load_misc_data() {
|
||||
MSP.send_message(MSPCodes.MSP_MISC, false, false, load_html);
|
||||
}
|
||||
loadChainer.setChain([
|
||||
mspHelper.loadStatus,
|
||||
mspHelper.loadMspIdent,
|
||||
mspHelper.loadBfConfig,
|
||||
mspHelper.loadMisc
|
||||
]);
|
||||
loadChainer.setExitPoint(load_html);
|
||||
loadChainer.execute();
|
||||
|
||||
function load_html() {
|
||||
$('#content').load("./tabs/setup.html", process_html);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false, load_ident);
|
||||
|
||||
function process_html() {
|
||||
// translate to user-selected language
|
||||
localize();
|
||||
|
@ -246,9 +244,19 @@ TABS.setup.initializeInstruments = function() {
|
|||
};
|
||||
};
|
||||
|
||||
TABS.setup.initialize3D = function (compatibility) {
|
||||
TABS.setup.initialize3D = function () {
|
||||
var self = this,
|
||||
loader, canvas, wrapper, renderer, camera, scene, light, light2, modelWrapper, model, model_file,
|
||||
loader,
|
||||
canvas,
|
||||
wrapper,
|
||||
renderer,
|
||||
camera,
|
||||
scene,
|
||||
light,
|
||||
light2,
|
||||
modelWrapper,
|
||||
model,
|
||||
model_file,
|
||||
useWebGlRenderer = false;
|
||||
|
||||
canvas = $('.model-and-info #canvas');
|
||||
|
@ -269,7 +277,7 @@ TABS.setup.initialize3D = function (compatibility) {
|
|||
|
||||
|
||||
// // modelWrapper adds an extra axis of rotation to avoid gimbal lock with the euler angles
|
||||
modelWrapper = new THREE.Object3D()
|
||||
modelWrapper = new THREE.Object3D();
|
||||
//
|
||||
// load the model including materials
|
||||
if (useWebGlRenderer) {
|
||||
|
@ -279,10 +287,8 @@ TABS.setup.initialize3D = function (compatibility) {
|
|||
}
|
||||
|
||||
// Temporary workaround for 'custom' model until akfreak's custom model is merged.
|
||||
var useLegacyCustomModel = false;
|
||||
if (model_file == 'custom') {
|
||||
model_file = 'fallback';
|
||||
useLegacyCustomModel = true;
|
||||
}
|
||||
|
||||
// setup scene
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue