mirror of
https://github.com/iNavFlight/inav-configurator.git
synced 2025-07-25 17:25:14 +03:00
Merge branch 'master' into release_4.1.0
This commit is contained in:
commit
9d89797bd4
19 changed files with 446 additions and 340 deletions
|
@ -1143,6 +1143,9 @@
|
|||
"portsFunction_DJI_FPV": {
|
||||
"message": "DJI FPV VTX"
|
||||
},
|
||||
"portsFunction_HDZERO_VTX": {
|
||||
"message": "HDZero VTX"
|
||||
},
|
||||
"portsFunction_IMU2": {
|
||||
"message": "Secondary IMU"
|
||||
},
|
||||
|
@ -3571,9 +3574,6 @@
|
|||
"platformConfiguration": {
|
||||
"message": "Platform configuration"
|
||||
},
|
||||
"platformHasFlaps": {
|
||||
"message": "Has flaps"
|
||||
},
|
||||
"mixerPreset": {
|
||||
"message": "Mixer preset"
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
var CONFIGURATOR = {
|
||||
// all versions are specified and compared using semantic versioning http://semver.org/
|
||||
'minfirmwareVersionAccepted': '3.0.0',
|
||||
'maxFirmwareVersionAccepted': '5.0.0', // Condition is < (lt) so we accept all in 3.1 branch
|
||||
'maxFirmwareVersionAccepted': '6.0.0', // Condition is < (lt) so we accept all in 4.x branch
|
||||
'connectionValid': false,
|
||||
'connectionValidCliOnly': false,
|
||||
'cliActive': false,
|
||||
|
|
|
@ -13,6 +13,7 @@ helper.defaultsDialog = (function () {
|
|||
|
||||
let data = [{
|
||||
"title": 'Mini Quad with 3"-7" propellers',
|
||||
"id": 2,
|
||||
"notRecommended": false,
|
||||
"reboot": true,
|
||||
"settings": [
|
||||
|
@ -582,6 +583,7 @@ helper.defaultsDialog = (function () {
|
|||
},
|
||||
{
|
||||
"title": 'Rovers & Boats',
|
||||
"id": 1,
|
||||
"notRecommended": false,
|
||||
"reboot": true,
|
||||
"settings": [
|
||||
|
@ -645,6 +647,7 @@ helper.defaultsDialog = (function () {
|
|||
},
|
||||
{
|
||||
"title": 'Keep current settings (Not recommended)',
|
||||
"id": 0,
|
||||
"notRecommended": true,
|
||||
"reboot": false,
|
||||
"settings": [
|
||||
|
@ -725,6 +728,11 @@ helper.defaultsDialog = (function () {
|
|||
let selectedDefaultPreset = data[$(event.currentTarget).data("index")];
|
||||
if (selectedDefaultPreset && selectedDefaultPreset.settings) {
|
||||
|
||||
if (selectedDefaultPreset.id == 0) {
|
||||
// Close applying preset dialog if keeping current settings.
|
||||
savingDefaultsModal.close();
|
||||
}
|
||||
|
||||
mspHelper.loadBfConfig(function () {
|
||||
privateScope.setFeaturesBits(selectedDefaultPreset)
|
||||
});
|
||||
|
|
2
js/fc.js
2
js/fc.js
|
@ -999,7 +999,7 @@ var FC = {
|
|||
'RC Channel 8', // 11
|
||||
'Gimbal Pitch', // 12
|
||||
'Gimbal Roll', // 13
|
||||
'Flaps', // 14
|
||||
'Flaperon Mode', // 14
|
||||
'RC Channel 9', // 15
|
||||
'RC Channel 10', // 16
|
||||
'RC Channel 11', // 17
|
||||
|
|
60
js/model.js
60
js/model.js
|
@ -2,10 +2,12 @@
|
|||
|
||||
const SERVO_GIMBAL_PITCH = 0,
|
||||
SERVO_GIMBAL_ROLL = 1,
|
||||
SERVO_ELEVATOR = 2,
|
||||
SERVO_FLAPPERON_1 = 3,
|
||||
SERVO_FLAPPERON_2 = 4,
|
||||
SERVO_RUDDER = 5,
|
||||
SERVO_ELEVATOR = 1,
|
||||
SERVO_ELEVON_1 = 1,
|
||||
SERVO_ELEVON_2 = 2,
|
||||
SERVO_FLAPPERON_1 = 2,
|
||||
SERVO_FLAPPERON_2 = 3,
|
||||
SERVO_RUDDER = 4,
|
||||
SERVO_BICOPTER_LEFT = 4,
|
||||
SERVO_BICOPTER_RIGHT = 5,
|
||||
SERVO_DUALCOPTER_LEFT = 4,
|
||||
|
@ -162,10 +164,10 @@ const mixerList = [
|
|||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
],
|
||||
servoMixer: [
|
||||
new ServoMixRule(SERVO_FLAPPERON_1, INPUT_STABILIZED_ROLL, 50, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_1, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_2, INPUT_STABILIZED_ROLL, -50, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_2, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(SERVO_ELEVON_1, INPUT_STABILIZED_ROLL, 50, 0),
|
||||
new ServoMixRule(SERVO_ELEVON_1, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(SERVO_ELEVON_2, INPUT_STABILIZED_ROLL, -50, 0),
|
||||
new ServoMixRule(SERVO_ELEVON_2, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
]
|
||||
}, // 8
|
||||
{
|
||||
|
@ -181,10 +183,10 @@ const mixerList = [
|
|||
new MotorMixRule(1.0, 0.0, 0.0, -0.1)
|
||||
],
|
||||
servoMixer: [
|
||||
new ServoMixRule(SERVO_FLAPPERON_1, INPUT_STABILIZED_ROLL, 50, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_1, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_2, INPUT_STABILIZED_ROLL, -50, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_2, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(SERVO_ELEVON_1, INPUT_STABILIZED_ROLL, 50, 0),
|
||||
new ServoMixRule(SERVO_ELEVON_1, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(SERVO_ELEVON_2, INPUT_STABILIZED_ROLL, -50, 0),
|
||||
new ServoMixRule(SERVO_ELEVON_2, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
]
|
||||
}, // 27
|
||||
{
|
||||
|
@ -289,6 +291,7 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: true,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
hasFlaps: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
|
@ -296,9 +299,9 @@ const mixerList = [
|
|||
servoMixer: [
|
||||
new ServoMixRule(SERVO_ELEVATOR, INPUT_STABILIZED_PITCH, 100, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_1, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_1, INPUT_FEATURE_FLAPS, 100, 0),
|
||||
/*new ServoMixRule(SERVO_FLAPPERON_1, INPUT_FEATURE_FLAPS, 100, 0),*/
|
||||
new ServoMixRule(SERVO_FLAPPERON_2, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_2, INPUT_FEATURE_FLAPS, -100, 0),
|
||||
/*new ServoMixRule(SERVO_FLAPPERON_2, INPUT_FEATURE_FLAPS, -100, 0),*/
|
||||
new ServoMixRule(SERVO_RUDDER, INPUT_STABILIZED_YAW, 100, 0),
|
||||
]
|
||||
}, // 14
|
||||
|
@ -448,6 +451,7 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: false,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
hasFlaps: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.3),
|
||||
new MotorMixRule(1.0, 0.0, 0.0, -0.3)
|
||||
|
@ -455,9 +459,9 @@ const mixerList = [
|
|||
servoMixer: [
|
||||
new ServoMixRule(SERVO_ELEVATOR, INPUT_STABILIZED_PITCH, 100, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_1, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_1, INPUT_FEATURE_FLAPS, 100, 0),
|
||||
/*new ServoMixRule(SERVO_FLAPPERON_1, INPUT_FEATURE_FLAPS, 100, 0),*/
|
||||
new ServoMixRule(SERVO_FLAPPERON_2, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_2, INPUT_FEATURE_FLAPS, -100, 0),
|
||||
/*new ServoMixRule(SERVO_FLAPPERON_2, INPUT_FEATURE_FLAPS, -100, 0),*/
|
||||
new ServoMixRule(SERVO_RUDDER, INPUT_STABILIZED_YAW, 100, 0),
|
||||
]
|
||||
},
|
||||
|
@ -469,16 +473,19 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: false,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
hasFlaps: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
],
|
||||
servoMixer: [
|
||||
new ServoMixRule(1, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
/*new ServoMixRule(1, INPUT_FEATURE_FLAPS, 100, 0),*/
|
||||
new ServoMixRule(2, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
new ServoMixRule(3, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
new ServoMixRule(4, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(4, INPUT_STABILIZED_YAW, -50, 0),
|
||||
new ServoMixRule(5, INPUT_STABILIZED_PITCH, -50, 0),
|
||||
new ServoMixRule(5, INPUT_STABILIZED_YAW, -50, 0)
|
||||
/*new ServoMixRule(2, INPUT_FEATURE_FLAPS, 100, 0),*/
|
||||
new ServoMixRule(3, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(3, INPUT_STABILIZED_YAW, -50, 0),
|
||||
new ServoMixRule(4, INPUT_STABILIZED_PITCH, -50, 0),
|
||||
new ServoMixRule(4, INPUT_STABILIZED_YAW, -50, 0)
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -493,11 +500,11 @@ const mixerList = [
|
|||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
],
|
||||
servoMixer: [
|
||||
new ServoMixRule(2, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
new ServoMixRule(3, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(1, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
new ServoMixRule(2, INPUT_STABILIZED_PITCH, 50, 0),
|
||||
new ServoMixRule(2, INPUT_STABILIZED_YAW, -50, 0),
|
||||
new ServoMixRule(3, INPUT_STABILIZED_PITCH, -50, 0),
|
||||
new ServoMixRule(3, INPUT_STABILIZED_YAW, -50, 0),
|
||||
new ServoMixRule(4, INPUT_STABILIZED_PITCH, -50, 0),
|
||||
new ServoMixRule(4, INPUT_STABILIZED_YAW, -50, 0),
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -508,13 +515,16 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: false,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
hasFlaps: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
],
|
||||
servoMixer: [
|
||||
new ServoMixRule(SERVO_ELEVATOR, INPUT_STABILIZED_PITCH, 100, 0),
|
||||
new ServoMixRule(SERVO_FLAPPERON_1, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
/*new ServoMixRule(SERVO_FLAPPERON_1, INPUT_FEATURE_FLAPS, 100, 0),*/
|
||||
new ServoMixRule(SERVO_FLAPPERON_2, INPUT_STABILIZED_ROLL, 100, 0),
|
||||
/*new ServoMixRule(SERVO_FLAPPERON_2, INPUT_FEATURE_FLAPS, 100, 0),*/
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -44,6 +44,7 @@ var mspHelper = (function (gui) {
|
|||
'DJI_FPV': 21,
|
||||
'SMARTPORT_MASTER': 23,
|
||||
'IMU2': 24,
|
||||
'HDZERO_VTX': 25,
|
||||
};
|
||||
|
||||
// Required for MSP_DEBUGMSG because console.log() doesn't allow omitting
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"minimum_chrome_version": "38",
|
||||
"version": "4.0.0",
|
||||
"version": "5.0.0",
|
||||
"author": "Several",
|
||||
"name": "INAV - Configurator",
|
||||
"short_name": "INAV",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "inav-configurator",
|
||||
"description": "INAV Configurator",
|
||||
"version": "4.0.0",
|
||||
"version": "5.0.0",
|
||||
"main": "main.html",
|
||||
"default_locale": "en",
|
||||
"scripts": {
|
||||
|
|
|
@ -84,6 +84,12 @@
|
|||
}
|
||||
|
||||
.mixer_btn_add {
|
||||
float: right;
|
||||
margin: 15px 0 10px;
|
||||
}
|
||||
|
||||
.mixer_btn_logic {
|
||||
float: left;
|
||||
margin: 15px 0 10px;
|
||||
}
|
||||
|
||||
|
|
|
@ -415,8 +415,42 @@ button {
|
|||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.tab-osd .third_left {
|
||||
float: left;
|
||||
width: calc(50% - 197px);
|
||||
}
|
||||
|
||||
.tab-osd .third_right {
|
||||
float: right;
|
||||
width: calc(50% - 197px);
|
||||
}
|
||||
|
||||
.tab-osd .preview {
|
||||
width: 360px;
|
||||
left: calc(50% - 197px);
|
||||
}
|
||||
|
||||
.tab-osd .preview_hd {
|
||||
width: 600px !important;
|
||||
left: calc(50% - 317px) !important;
|
||||
}
|
||||
|
||||
.tab-osd .hd_43_left {
|
||||
border-left: 1px solid red;
|
||||
position: absolute;
|
||||
left: 60px;
|
||||
height: calc(100% - 27px);
|
||||
}
|
||||
|
||||
.tab-osd .hd_43_right {
|
||||
border-right: 1px solid red;
|
||||
position: absolute;
|
||||
right: 60px;
|
||||
height: calc(100% - 27px);
|
||||
}
|
||||
|
||||
.tab-osd .preview_hd_side {
|
||||
width: calc(50% - 317px) !important;
|
||||
}
|
||||
|
||||
.tab-osd .preview {
|
||||
|
|
|
@ -244,14 +244,16 @@
|
|||
.show {
|
||||
width:110px;
|
||||
float:right;
|
||||
margin-right:3px;
|
||||
}
|
||||
|
||||
.show a {
|
||||
margin-left: 10px;
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
|
||||
.show.unusedPIDsHidden {
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
.tab-pid_tuning .helpicon {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
@ -328,6 +330,7 @@
|
|||
.tab-pid_tuning .resetbt {
|
||||
width: 140px;
|
||||
float: right;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
.tab-pid_tuning .right {
|
||||
|
|
|
@ -36,32 +36,19 @@ TABS.auxiliary.initialize = function (callback) {
|
|||
|
||||
MSP.send_message(MSPCodes.MSP_BOXNAMES, false, false, get_mode_ranges);
|
||||
|
||||
// This object separates out the dividers. This is also used to order the modes
|
||||
const modeSections = {};
|
||||
modeSections["ARM"] = "Arming";
|
||||
modeSections["ANGLE"] = "Flight Modes";
|
||||
modeSections["NAV RTH"] = "Navigation Modes";
|
||||
modeSections["NAV ALTHOLD"] = "Flight Mode Modifiers";
|
||||
modeSections["AUTO TUNE"] = "Fixed Wing";
|
||||
modeSections["FPV ANGLE MIX"] = "Multi-rotor";
|
||||
modeSections["OSD OFF"] = "OSD Modes";
|
||||
modeSections["CAMSTAB"] = "FPV Camera Modes";
|
||||
modeSections["BEEPER"] = "Misc Modes";
|
||||
modeSections["Arming"] = ["ARM", "PREARM"];
|
||||
modeSections["Flight Modes"] = ["ANGLE", "HORIZON", "MANUAL"];
|
||||
modeSections["Navigation Modes"] = ["NAV COURSE HOLD", "NAV CRUISE", "NAV POSHOLD", "NAV RTH", "NAV WP", "GCS NAV"];
|
||||
modeSections["Flight Mode Modifiers"] = ["NAV ALTHOLD", "HEADING HOLD", "AIR MODE", "SOARING", "SURFACE"];
|
||||
modeSections["Fixed Wing"] = ["AUTO TUNE", "SERVO AUTOTRIM", "AUTO LEVEL", "NAV LAUNCH", "LOITER CHANGE", "FLAPERON", "TURN ASSIST"];
|
||||
modeSections["Multi-rotor"] = ["FPV ANGLE MIX", "TURTLE", "MC BRAKING", "HEADFREE", "HEADADJ"];
|
||||
modeSections["OSD Modes"] = ["OSD OFF", "OSD ALT 1", "OSD ALT 2", "OSD ALT 3"];
|
||||
modeSections["FPV Camera Modes"] = ["CAMSTAB", "CAMERA CONTROL 1", "CAMERA CONTROL 2", "CAMERA CONTROL 3"];
|
||||
modeSections["Misc Modes"] = ["BEEPER", "LEDS OFF", "LIGHTS", "HOME RESET", "WP PLANNER", "BLACKBOX", "FAILSAFE", "KILLSWITCH", "TELEMETRY", "MSP RC OVERRIDE", "USER1", "USER2"];
|
||||
|
||||
function sort_modes_for_display() {
|
||||
// This array defines the order that the modes are displayed in the configurator modes page
|
||||
const configuratorBoxOrder = [
|
||||
"ARM", "PREARM", // Arming
|
||||
"ANGLE", "HORIZON", "MANUAL", // Flight modes
|
||||
"NAV RTH", "NAV COURSE HOLD", "NAV CRUISE", "NAV POSHOLD", "NAV WP", "GCS NAV", // Navigation modes
|
||||
"NAV ALTHOLD", "HEADING HOLD", "AIR MODE", "SURFACE", // Flight mode modifiers
|
||||
"AUTO TUNE", "SERVO AUTOTRIM", "AUTO LEVEL", "NAV LAUNCH", "LOITER CHANGE", "FLAPERON", "TURN ASSIST", // Fixed wing specific
|
||||
"FPV ANGLE MIX", "TURTLE", "MC BRAKING", "HEADFREE", "HEADADJ", // Multi-rotor specific
|
||||
"OSD OFF", "OSD ALT 1", "OSD ALT 2", "OSD ALT 3", // OSD
|
||||
"CAMSTAB", "CAMERA CONTROL 1", "CAMERA CONTROL 2", "CAMERA CONTROL 3", // FPV Camera
|
||||
"BEEPER", "LEDS OFF", "LIGHTS", "HOME RESET", "BLACKBOX", "FAILSAFE", "KILLSWITCH", "TELEMETRY", // Misc
|
||||
"MSP RC OVERRIDE", "USER1", "USER2"
|
||||
];
|
||||
|
||||
// Sort the modes
|
||||
var tmpAUX_CONFIG = [];
|
||||
var tmpAUX_CONFIG_IDS =[];
|
||||
|
@ -76,9 +63,11 @@ TABS.auxiliary.initialize = function (callback) {
|
|||
AUX_CONFIG = [];
|
||||
AUX_CONFIG_IDS = [];
|
||||
|
||||
for (i=0; i<configuratorBoxOrder.length; i++) {
|
||||
for (let categoryModesIndex in modeSections) {
|
||||
let categoryModes = modeSections[categoryModesIndex];
|
||||
for (cM=0; cM<categoryModes.length; cM++){
|
||||
for(j=0; j<tmpAUX_CONFIG.length; j++) {
|
||||
if (configuratorBoxOrder[i] === tmpAUX_CONFIG[j]) {
|
||||
if (categoryModes[cM] === tmpAUX_CONFIG[j]) {
|
||||
AUX_CONFIG[sortedID] = tmpAUX_CONFIG[j];
|
||||
AUX_CONFIG_IDS[sortedID] = tmpAUX_CONFIG_IDS[j];
|
||||
ORIG_AUX_CONFIG_IDS[sortedID++] = j;
|
||||
|
@ -87,8 +76,9 @@ TABS.auxiliary.initialize = function (callback) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There are modes that are missing from the configuratorBoxOrder array. Add them to the end until they are ordered correctly.
|
||||
// There are modes that are missing from the modeSections object. Add them to the end until they are ordered correctly.
|
||||
if (tmpAUX_CONFIG.length > AUX_CONFIG.length) {
|
||||
for (i=0; i<tmpAUX_CONFIG.length; i++) {
|
||||
found = false;
|
||||
|
@ -214,11 +204,23 @@ TABS.auxiliary.initialize = function (callback) {
|
|||
|
||||
configureRangeTemplate(auxChannelCount);
|
||||
|
||||
var modeTableBodyElement = $('.tab-auxiliary .modes tbody')
|
||||
var modeTableBodyElement = $('.tab-auxiliary .modes tbody');
|
||||
let modeSelectionID = "";
|
||||
let modeSelectionRange = "";
|
||||
|
||||
for (var modeIndex = 0; modeIndex < AUX_CONFIG.length; modeIndex++) {
|
||||
|
||||
if (AUX_CONFIG[modeIndex] in modeSections) {
|
||||
var newSection = createModeSection(modeSections[AUX_CONFIG[modeIndex]]);
|
||||
// Get current mode category
|
||||
for (modeSelectionRange in modeSections) {
|
||||
if (modeSections[modeSelectionRange].indexOf(AUX_CONFIG[modeIndex]) != -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create divider if needed
|
||||
if (modeSelectionRange != modeSelectionID) {
|
||||
modeSelectionID = modeSelectionRange;
|
||||
var newSection = createModeSection(modeSelectionRange);
|
||||
modeTableBodyElement.append(newSection);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,6 @@
|
|||
<span data-i18n="platformType"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="has-flaps-wrapper" class="checkbox">
|
||||
<input type="checkbox" id="has-flaps" class="toggle" />
|
||||
<label for="has-flaps">
|
||||
<span data-i18n="platformHasFlaps"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -118,12 +112,12 @@
|
|||
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="btn default_btn narrow pull-left mixer_btn_add">
|
||||
<a href="#" data-role="role-logic-conditions-open" data-i18n="tabLogicConditions"></a>
|
||||
</div>
|
||||
<div class="btn default_btn narrow pull-right green mixer_btn_add">
|
||||
<a href="#" data-role="role-servo-add" data-i18n="servoMixerAdd"></a>
|
||||
</div>
|
||||
<div class="btn default_btn narrow pull-left mixer_btn_logic">
|
||||
<a href="#" data-role="role-logic-conditions-open" data-i18n="tabLogicConditions"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -124,6 +124,10 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
|
||||
GUI.fillSelect($row.find(".mix-rule-input"), FC.getServoMixInputNames(), servoRule.getInput());
|
||||
|
||||
if (!MIXER_CONFIG.hasFlaps) {
|
||||
$row.find(".mix-rule-input").children('option[value="14"]').remove();
|
||||
}
|
||||
|
||||
$row.find(".mix-rule-input").val(servoRule.getInput()).change(function () {
|
||||
servoRule.setInput($(this).val());
|
||||
updateFixedValueVisibility($row, $(this));
|
||||
|
@ -272,8 +276,6 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
|
||||
let $platformSelect = $('#platform-type'),
|
||||
platforms = helper.platform.getList(),
|
||||
$hasFlapsWrapper = $('#has-flaps-wrapper'),
|
||||
$hasFlaps = $('#has-flaps'),
|
||||
$mixerPreset = $('#mixer-preset'),
|
||||
$wizardButton = $("#mixer-wizard");
|
||||
|
||||
|
@ -354,30 +356,12 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
}
|
||||
}
|
||||
|
||||
$hasFlaps.prop("checked", MIXER_CONFIG.hasFlaps);
|
||||
$hasFlaps.change(function () {
|
||||
if ($(this).is(":checked")) {
|
||||
MIXER_CONFIG.hasFlaps = 1;
|
||||
} else {
|
||||
MIXER_CONFIG.hasFlaps = 0;
|
||||
}
|
||||
});
|
||||
$hasFlaps.change();
|
||||
|
||||
$platformSelect.change(function () {
|
||||
MIXER_CONFIG.platformType = parseInt($platformSelect.val(), 10);
|
||||
currentPlatform = helper.platform.getById(MIXER_CONFIG.platformType);
|
||||
|
||||
var $platformSelectParent = $platformSelect.parent('.select');
|
||||
|
||||
if (currentPlatform.flapsPossible) {
|
||||
$hasFlapsWrapper.removeClass('is-hidden');
|
||||
$platformSelectParent.removeClass('no-bottom-border');
|
||||
} else {
|
||||
$hasFlapsWrapper.addClass('is-hidden');
|
||||
$platformSelectParent.addClass('no-bottom-border');
|
||||
}
|
||||
|
||||
fillMixerPreset();
|
||||
$mixerPreset.change();
|
||||
});
|
||||
|
@ -430,6 +414,7 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
$('#load-mixer-button').click(function () {
|
||||
helper.mixer.loadServoRules(currentMixerPreset);
|
||||
helper.mixer.loadMotorRules(currentMixerPreset);
|
||||
MIXER_CONFIG.hasFlaps = (currentMixerPreset.hasFlaps === true) ? true : false;
|
||||
renderServoMixRules();
|
||||
renderMotorMixRules();
|
||||
renderOutputMapping();
|
||||
|
|
|
@ -25,19 +25,20 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cf_column twothird">
|
||||
<div class="gui_box grey preview" style="float: left; position: fixed;">
|
||||
<div class="gui_box_titlebar image">
|
||||
<div class="gui_box preview" style="float: left; position: fixed;">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="osd_preview_title"></div>
|
||||
</div>
|
||||
<div class="display-layout">
|
||||
<div class="col right">
|
||||
<div class="left_43_margin"></div>
|
||||
<div class="right_43_margin"></div>
|
||||
<div class="preview">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cf_column third_right" style="width: calc(100% - 377px);">
|
||||
<div class="cf_column third_right">
|
||||
<div class="gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="osd_video_format"></div>
|
||||
|
@ -236,7 +237,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="fontmanagercontent" style="display:none; width:712px;">
|
||||
<div class="font-picker" style="margin-bottom: 10px;">
|
||||
<h1 class="tab_title">Font:</h1>
|
||||
|
@ -263,9 +263,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="content_toolbar supported hide">
|
||||
<div class="btn">
|
||||
|
|
136
tabs/osd.js
136
tabs/osd.js
|
@ -454,7 +454,6 @@ OSD.initData = function () {
|
|||
item_count: 0,
|
||||
items: [],
|
||||
groups: {},
|
||||
display_items: [],
|
||||
preview: [],
|
||||
isDjiHdFpv: false
|
||||
};
|
||||
|
@ -512,19 +511,27 @@ OSD.DjiElements = {
|
|||
};
|
||||
|
||||
OSD.constants = {
|
||||
VISIBLE: 0x0800,
|
||||
VISIBLE: 0x2000,
|
||||
VIDEO_TYPES: [
|
||||
'AUTO',
|
||||
'PAL',
|
||||
'NTSC'
|
||||
'NTSC',
|
||||
'HD'
|
||||
],
|
||||
VIDEO_LINES: {
|
||||
PAL: 16,
|
||||
NTSC: 13
|
||||
NTSC: 13,
|
||||
HD: 18
|
||||
},
|
||||
VIDEO_COLS: {
|
||||
PAL: 30,
|
||||
NTSC: 30,
|
||||
HD: 50
|
||||
},
|
||||
VIDEO_BUFFER_CHARS: {
|
||||
PAL: 480,
|
||||
NTSC: 390
|
||||
NTSC: 390,
|
||||
HD: 900
|
||||
},
|
||||
UNIT_TYPES: [
|
||||
{name: 'osdUnitImperial', value: 0},
|
||||
|
@ -2003,14 +2010,39 @@ OSD.updateDisplaySize = function () {
|
|||
if (video_type == 'AUTO') {
|
||||
video_type = 'PAL';
|
||||
}
|
||||
// compute the size
|
||||
|
||||
// save the original OSD element positions.
|
||||
var origPos = [];
|
||||
for (var ii = 0; ii < OSD.data.items.length; ii++) {
|
||||
origPos.push(OSD.msp.helpers.pack.position(OSD.data.items[ii]));
|
||||
}
|
||||
|
||||
// save the new video type and cols per line
|
||||
FONT.constants.SIZES.LINE = OSD.constants.VIDEO_COLS[video_type];
|
||||
OSD.constants.VIDEO_TYPES[OSD.data.video_system] = video_type;
|
||||
|
||||
// set the new display size
|
||||
OSD.data.display_size = {
|
||||
x: FONT.constants.SIZES.LINE,
|
||||
y: OSD.constants.VIDEO_LINES[video_type],
|
||||
total: null
|
||||
total: OSD.constants.VIDEO_BUFFER_CHARS[video_type]
|
||||
};
|
||||
|
||||
OSD.constants.VIDEO_TYPES[OSD.data.video_system] = video_type;
|
||||
// recalculate the OSD element positions for the new cols per line
|
||||
for (var ii = 0; ii < OSD.data.items.length; ii++) {
|
||||
var item = OSD.msp.helpers.unpack.position(origPos[ii]);
|
||||
// do not recalculate anything not visible or outside of the screen
|
||||
if (item.isVisible && item.x < OSD.data.display_size.x && item.y < OSD.data.display_size.y) {
|
||||
OSD.data.items[ii] = item;
|
||||
}
|
||||
}
|
||||
|
||||
// set the preview size
|
||||
$('.third_left').toggleClass('preview_hd_side', (video_type == 'HD'))
|
||||
$('.preview').toggleClass('preview_hd cut43_left', (video_type == 'HD'))
|
||||
$('.third_right').toggleClass('preview_hd_side', (video_type == 'HD'))
|
||||
$('.left_43_margin').toggleClass('hd_43_left', (video_type == 'HD'))
|
||||
$('.right_43_margin').toggleClass('hd_43_right', (video_type == 'HD'))
|
||||
};
|
||||
|
||||
OSD.saveAlarms = function(callback) {
|
||||
|
@ -2034,27 +2066,36 @@ OSD.saveItem = function(item, callback) {
|
|||
//noinspection JSUnusedLocalSymbols
|
||||
OSD.msp = {
|
||||
/**
|
||||
* Note, unsigned 16 bit int for position ispacked:
|
||||
* Unsigned 16 bit int for position is packed:
|
||||
* 0: unused
|
||||
* v: visible flag
|
||||
* b: blink flag
|
||||
* y: y coordinate
|
||||
* x: x coordinate
|
||||
* 0000 vbyy yyyx xxxx
|
||||
* 00vb yyyy yyxx xxxx
|
||||
*/
|
||||
helpers: {
|
||||
unpack: {
|
||||
position: function (bits) {
|
||||
var display_item = {};
|
||||
// size * y + x
|
||||
display_item.position = FONT.constants.SIZES.LINE * ((bits >> 5) & 0x001F) + (bits & 0x001F);
|
||||
display_item.x = bits & 0x3F;
|
||||
display_item.y = (bits >> 6) & 0x3F;
|
||||
display_item.position = (display_item.y) * FONT.constants.SIZES.LINE + (display_item.x);
|
||||
display_item.isVisible = (bits & OSD.constants.VISIBLE) != 0;
|
||||
return display_item;
|
||||
}
|
||||
},
|
||||
calculate: {
|
||||
coords: function(display_item) {
|
||||
display_item.x = (display_item.position % FONT.constants.SIZES.LINE) & 0x3F;
|
||||
display_item.y = (display_item.position / FONT.constants.SIZES.LINE) & 0x3F;
|
||||
return display_item;
|
||||
}
|
||||
},
|
||||
pack: {
|
||||
position: function (display_item) {
|
||||
return (display_item.isVisible ? 0x0800 : 0) | (((display_item.position / FONT.constants.SIZES.LINE) & 0x001F) << 5) | (display_item.position % FONT.constants.SIZES.LINE);
|
||||
return (display_item.isVisible ? 0x2000 : 0)
|
||||
| ((display_item.y & 0x3F) << 6) | (display_item.x & 0x3F);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2439,8 +2480,8 @@ OSD.GUI.updateFields = function() {
|
|||
// Ensure the element is inside the viewport, at least partially.
|
||||
// In that case move it to the very first row/col, otherwise there's
|
||||
// no way to reposition items that are outside the viewport.
|
||||
if (itemData.position >= OSD.data.preview.length) {
|
||||
itemData.position = 0;
|
||||
if (itemData.x > OSD.data.display_size.x || itemData.y > OSD.data.display_size.y) {
|
||||
itemData.x = itemData.y = itemData.position = 0;
|
||||
}
|
||||
$position.show();
|
||||
} else {
|
||||
|
@ -2461,6 +2502,7 @@ OSD.GUI.updateFields = function() {
|
|||
var item = $(this).data('item');
|
||||
var itemData = OSD.data.items[item.id];
|
||||
itemData.position = parseInt($(this).val());
|
||||
OSD.msp.helpers.calculate.coords(itemData);
|
||||
OSD.GUI.saveItem(item);
|
||||
}))
|
||||
);
|
||||
|
@ -2577,14 +2619,6 @@ OSD.GUI.updateMapPreview = function(mapCenter, name, directionSymbol, centerSymb
|
|||
OSD.GUI.updatePreviews = function() {
|
||||
// buffer the preview;
|
||||
OSD.data.preview = [];
|
||||
OSD.data.display_size.total = OSD.data.display_size.x * OSD.data.display_size.y;
|
||||
for (var ii = 0; ii < OSD.data.display_items.length; ii++) {
|
||||
var field = OSD.data.display_items[ii];
|
||||
// reset fields that somehow end up off the screen
|
||||
if (field.position > OSD.data.display_size.total) {
|
||||
field.position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// clear the buffer
|
||||
for (i = 0; i < OSD.data.display_size.total; i++) {
|
||||
|
@ -2601,6 +2635,12 @@ OSD.GUI.updatePreviews = function() {
|
|||
if (!itemData.isVisible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (itemData.x >= OSD.data.display_size.x)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// DJI HD FPV: Hide elements that only appear in craft name
|
||||
if (OSD.DjiElements.craftNameElements.includes(item.name) &&
|
||||
$('#djiUnsupportedElements').find('input').is(':checked')) {
|
||||
|
@ -2650,16 +2690,16 @@ OSD.GUI.updatePreviews = function() {
|
|||
item.preview_img.style.pointerEvents = 'none';
|
||||
}
|
||||
|
||||
var centerishPosition = 255;
|
||||
|
||||
// AHI is one line up with NTSC (less lines) compared to PAL
|
||||
if (OSD.constants.VIDEO_TYPES[OSD.data.video_system] == 'NTSC')
|
||||
centerishPosition -= OSD.data.display_size.x;
|
||||
var centerPosition = (OSD.data.display_size.x * OSD.data.display_size.y / 2);
|
||||
if (OSD.data.display_size.y % 2 == 0) {
|
||||
centerPosition += OSD.data.display_size.x / 2;
|
||||
}
|
||||
|
||||
// artificial horizon
|
||||
if ($('input[name="ARTIFICIAL_HORIZON"]').prop('checked')) {
|
||||
for (i = 0; i < 9; i++) {
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition - 4 + i, SYM.AH_BAR9_0 + 4);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition - 4 + i, SYM.AH_BAR9_0 + 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2668,21 +2708,21 @@ OSD.GUI.updatePreviews = function() {
|
|||
crsHNumber = Settings.getInputValue('osd_crosshairs_style');
|
||||
if (crsHNumber == 1) {
|
||||
// AIRCRAFT style
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition - 2, SYM.AH_AIRCRAFT0);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition - 1, SYM.AH_AIRCRAFT1);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition, SYM.AH_AIRCRAFT2);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition + 1, SYM.AH_AIRCRAFT3);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition + 2, SYM.AH_AIRCRAFT4);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition - 2, SYM.AH_AIRCRAFT0);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition - 1, SYM.AH_AIRCRAFT1);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition, SYM.AH_AIRCRAFT2);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition + 1, SYM.AH_AIRCRAFT3);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition + 2, SYM.AH_AIRCRAFT4);
|
||||
} else if ((crsHNumber > 1) && (crsHNumber < 8)) {
|
||||
// TYPES 3 to 8 (zero indexed)
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition - 1, SYM.AH_CROSSHAIRS[crsHNumber][0]);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition, SYM.AH_CROSSHAIRS[crsHNumber][1]);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition + 1, SYM.AH_CROSSHAIRS[crsHNumber][2]);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition - 1, SYM.AH_CROSSHAIRS[crsHNumber][0]);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition, SYM.AH_CROSSHAIRS[crsHNumber][1]);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition + 1, SYM.AH_CROSSHAIRS[crsHNumber][2]);
|
||||
} else {
|
||||
// DEFAULT or unknown style
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition - 1, SYM.AH_CENTER_LINE);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition, SYM.AH_CROSSHAIRS[crsHNumber]);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition + 1, SYM.AH_CENTER_LINE_RIGHT);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition - 1, SYM.AH_CENTER_LINE);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition, SYM.AH_CROSSHAIRS[crsHNumber]);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition + 1, SYM.AH_CENTER_LINE_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2691,21 +2731,17 @@ OSD.GUI.updatePreviews = function() {
|
|||
var hudwidth = OSD.constants.AHISIDEBARWIDTHPOSITION;
|
||||
var hudheight = OSD.constants.AHISIDEBARHEIGHTPOSITION;
|
||||
for (i = -hudheight; i <= hudheight; i++) {
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition - hudwidth + (i * FONT.constants.SIZES.LINE), SYM.AH_DECORATION);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition + hudwidth + (i * FONT.constants.SIZES.LINE), SYM.AH_DECORATION);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition - hudwidth + (i * FONT.constants.SIZES.LINE), SYM.AH_DECORATION);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition + hudwidth + (i * FONT.constants.SIZES.LINE), SYM.AH_DECORATION);
|
||||
}
|
||||
// AH level indicators
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition - hudwidth + 1, SYM.AH_LEFT);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerishPosition + hudwidth - 1, SYM.AH_RIGHT);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition - hudwidth + 1, SYM.AH_LEFT);
|
||||
OSD.GUI.checkAndProcessSymbolPosition(centerPosition + hudwidth - 1, SYM.AH_RIGHT);
|
||||
}
|
||||
|
||||
var mapCenter = (OSD.data.display_size.x * OSD.data.display_size.y / 2);
|
||||
if (OSD.data.display_size.y % 2 == 0) {
|
||||
mapCenter += OSD.data.display_size.x / 2;
|
||||
}
|
||||
OSD.GUI.updateMapPreview(mapCenter, 'MAP_NORTH', 'N', SYM.HOME);
|
||||
OSD.GUI.updateMapPreview(mapCenter, 'MAP_TAKEOFF', 'T', SYM.HOME);
|
||||
OSD.GUI.updateMapPreview(mapCenter, 'RADAR', null, SYM.DIR_TO_HOME);
|
||||
OSD.GUI.updateMapPreview(centerPosition, 'MAP_NORTH', 'N', SYM.HOME);
|
||||
OSD.GUI.updateMapPreview(centerPosition, 'MAP_TAKEOFF', 'T', SYM.HOME);
|
||||
OSD.GUI.updateMapPreview(centerPosition, 'RADAR', null, SYM.DIR_TO_HOME);
|
||||
|
||||
// render
|
||||
var $preview = $('.display-layout .preview').empty();
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
<div class="default_btn show">
|
||||
<a href="#" id="showAllPids">Show all PIDs</a>
|
||||
</div>
|
||||
<div class="default_btn resetbt">
|
||||
<a href="#" id="resetDefaults">Select New Defaults</a>
|
||||
</div>
|
||||
<div class="default_btn resetbt">
|
||||
<a href="#" id="resetPIDs">Reset PID Controller</a>
|
||||
</div>
|
||||
|
|
|
@ -140,9 +140,11 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
if($(this).text() == "Show all PIDs") {
|
||||
$('.tab-pid_tuning table.pid_tuning').show();
|
||||
$(this).text('Hide unused PIDs');
|
||||
$('.show').addClass('unusedPIDsHidden');
|
||||
} else {
|
||||
hideUnusedPids(CONFIG.activeSensors);
|
||||
$(this).text('Show all PIDs');
|
||||
$('.show').removeClass('unusedPIDsHidden');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -151,6 +153,21 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
updateActivatedTab();
|
||||
});
|
||||
|
||||
$('#resetDefaults').on('click', function() {
|
||||
mspHelper.setSetting("applied_defaults", 0, function() {
|
||||
mspHelper.saveToEeprom( function () {
|
||||
GUI.log(chrome.i18n.getMessage('configurationEepromSaved'));
|
||||
|
||||
GUI.tab_switch_cleanup(function () {
|
||||
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||
GUI.handleReconnect();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
pid_and_rc_to_form();
|
||||
|
||||
let $magHoldYawRate = $("#magHoldYawRate");
|
||||
|
@ -173,6 +190,9 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
// UI Hooks
|
||||
|
||||
$('a.refresh').click(function () {
|
||||
$("#content-watermark").remove();
|
||||
$(".tab-pid_tuning").remove();
|
||||
|
||||
GUI.tab_switch_cleanup(function () {
|
||||
GUI.log(chrome.i18n.getMessage('pidTuningDataRefreshed'));
|
||||
TABS.pid_tuning.initialize();
|
||||
|
|
|
@ -93,6 +93,12 @@ TABS.ports.initialize = function (callback) {
|
|||
maxPorts: 1 }
|
||||
);
|
||||
|
||||
functionRules.push({
|
||||
name: 'HDZERO_VTX',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1 }
|
||||
);
|
||||
|
||||
functionRules.push({
|
||||
name: 'SMARTPORT_MASTER',
|
||||
groups: ['peripherals'],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue