diff --git a/_locales/en/messages.json b/_locales/en/messages.json index d38232f1..6a27f002 100755 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1584,6 +1584,9 @@ "pidTuning_gyro_dyn_lpf_max_hz_help": { "message": "Defines the gyro LPF cutoff frequency at maximum throttle. When throttle is decreased, LPF cutoff frequency is decreased as well, down to the minimum cutoff frequency." }, + "loadedMixerProfile": { + "message": "Loaded Mixer Profile: $1, Check modes tab: MIXER PROFILE 2 if you don't see the changes" + }, "loadedBatteryProfile": { "message": "Loaded Battery Profile: $1" }, @@ -4409,6 +4412,9 @@ "no_waypoints_to_save": { "message": "No waypoints to save !" }, + "mixerThrottleWarning": { + "message": "Warning:value beyond normal operation range." + }, "servoMixer": { "message": "Servo mixer" }, @@ -4892,6 +4898,12 @@ "motor_direction_inverted_hint": { "message": "Enable if the motor direction is reversed and the props are mounted in the opposite direction." }, + "mixer_pid_profile_linking": { + "message": "PID Profile will use same index as Mixer Profile index" + }, + "mixer_pid_profile_linking_hint": { + "message": "mixer_pid_profile_linking: Enable on both Mixer Profile if you want PID Profile switching handled by Mixer Profile switching(Recommend in vtol/mixed plaform type setup)" + }, "blackboxFields": { "message": "Blackbox fields" }, @@ -5207,14 +5219,20 @@ "sensorDataFlashFreeSpace": { "message": "Dataflash: free space" }, + "mixerProfile1": { + "message": "Mixer profile 1" + }, + "mixerProfile2": { + "message": "Mixer profile 2" + }, "sensorProfile1": { - "message": "Profile 1" + "message": "PID profile 1" }, "sensorProfile2": { - "message": "Profile 2" + "message": "PID profile 2" }, "sensorProfile3": { - "message": "Profile 3" + "message": "PID profile 3" }, "sensorBatteryProfile1": { "message": "Battery profile 1" diff --git a/js/defaults_dialog.js b/js/defaults_dialog.js index 0a57d701..9f9641b1 100644 --- a/js/defaults_dialog.js +++ b/js/defaults_dialog.js @@ -822,10 +822,6 @@ helper.defaultsDialog = (function () { key: "nav_fw_launch_climb_angle", value: 25 }, - { - key: "motorstop_on_low", - value: "ON" - }, ], }, { @@ -1039,10 +1035,6 @@ helper.defaultsDialog = (function () { key: "nav_fw_launch_climb_angle", value: 25 }, - { - key: "motorstop_on_low", - value: "ON" - }, ], }, { @@ -1201,6 +1193,7 @@ helper.defaultsDialog = (function () { MIXER_CONFIG.platformType = currentMixerPreset.platform; MIXER_CONFIG.appliedMixerPreset = selectedDefaultPreset.mixerToApply; + MIXER_CONFIG.motorStopOnLow = (currentMixerPreset.motorStopOnLow === true) ? true : false; MIXER_CONFIG.hasFlaps = (currentMixerPreset.hasFlaps === true) ? true : false; SERVO_RULES.cleanup(); diff --git a/js/fc.js b/js/fc.js index 6f84aca3..a85bc59a 100644 --- a/js/fc.js +++ b/js/fc.js @@ -118,6 +118,7 @@ var FC = { i2cError: 0, activeSensors: 0, mode: [], + mixer_profile: 0, profile: 0, battery_profile: 0, uid: [0, 0, 0], diff --git a/js/gui.js b/js/gui.js index 7a70df4f..db2f9bd0 100644 --- a/js/gui.js +++ b/js/gui.js @@ -261,6 +261,7 @@ GUI_control.prototype.updateStatusBar = function() { }; GUI_control.prototype.updateProfileChange = function() { + $('#mixerprofilechange').val(CONFIG.mixer_profile); $('#profilechange').val(CONFIG.profile); $('#batteryprofilechange').val(CONFIG.battery_profile); }; diff --git a/js/model.js b/js/model.js index 806140b1..aaeafd7a 100644 --- a/js/model.js +++ b/js/model.js @@ -350,6 +350,7 @@ const mixerList = [ enabled: true, legacy: true, platform: PLATFORM_AIRPLANE, + motorStopOnLow: true, motorMixer: [ new MotorMixRule(1.0, 0.0, 0.0, 0.0), ], @@ -373,6 +374,7 @@ const mixerList = [ enabled: true, legacy: false, platform: PLATFORM_AIRPLANE, + motorStopOnLow: true, motorMixer: [ new MotorMixRule(1.0, 0.0, 0.0, 0.1), new MotorMixRule(1.0, 0.0, 0.0, -0.1) @@ -399,6 +401,7 @@ const mixerList = [ enabled: true, legacy: true, platform: PLATFORM_AIRPLANE, + motorStopOnLow: true, hasFlaps: true, motorMixer: [ new MotorMixRule(1.0, 0.0, 0.0, 0.0), @@ -427,6 +430,7 @@ const mixerList = [ enabled: true, legacy: false, platform: PLATFORM_AIRPLANE, + motorStopOnLow: true, hasFlaps: true, motorMixer: [ new MotorMixRule(1.0, 0.0, 0.0, 0.3), @@ -456,6 +460,7 @@ const mixerList = [ enabled: true, legacy: false, platform: PLATFORM_AIRPLANE, + motorStopOnLow: true, hasFlaps: true, motorMixer: [ new MotorMixRule(1.0, 0.0, 0.0, 0.0), @@ -486,6 +491,7 @@ const mixerList = [ enabled: true, legacy: false, platform: PLATFORM_AIRPLANE, + motorStopOnLow: true, hasFlaps: true, motorMixer: [ new MotorMixRule(1.0, 0.0, 0.0, 0.3), @@ -516,6 +522,7 @@ const mixerList = [ enabled: true, legacy: false, platform: PLATFORM_AIRPLANE, + motorStopOnLow: true, motorMixer: [ new MotorMixRule(1.0, 0.0, 0.0, 0.0), ], @@ -542,6 +549,7 @@ const mixerList = [ legacy: false, platform: PLATFORM_AIRPLANE, hasFlaps: true, + motorStopOnLow: true, motorMixer: [ new MotorMixRule(1.0, 0.0, 0.0, 0.0), ], @@ -568,6 +576,7 @@ const mixerList = [ enabled: false, legacy: true, platform: PLATFORM_AIRPLANE, + motorStopOnLow: true, motorMixer: [], servoMixer: [] }, // 24 diff --git a/js/motorMixRule.js b/js/motorMixRule.js index 16b241e1..06957821 100644 --- a/js/motorMixRule.js +++ b/js/motorMixRule.js @@ -6,7 +6,7 @@ var MotorMixRule = function (throttle, roll, pitch, yaw) { var self = {}; self.fromMsp = function (mspThrottle, mspRoll, mspPitch, mspYaw) { - throttle = mspThrottle / 1000; + throttle = Math.round(((mspThrottle / 1000) - 2) * 1000) / 1000; roll = Math.round(((mspRoll / 1000) - 2) * 1000) / 1000; pitch = Math.round(((mspPitch / 1000) - 2) * 1000) / 1000; yaw = Math.round(((mspYaw / 1000) - 2) * 1000) / 1000; @@ -17,11 +17,11 @@ var MotorMixRule = function (throttle, roll, pitch, yaw) { }; self.getThrottle = function () { - return constrain(parseFloat(throttle, 10), 0, 1); + return constrain(parseFloat(throttle, 10), -2, 2); }; self.getThrottleForMsp = function () { - return self.getThrottle() * 1000; + return (self.getThrottle()+2) * 1000; }; self.setThrottle = function (data) { diff --git a/js/motorMixerRuleCollection.js b/js/motorMixerRuleCollection.js index 6a5a6c40..a995f867 100644 --- a/js/motorMixerRuleCollection.js +++ b/js/motorMixerRuleCollection.js @@ -5,6 +5,7 @@ var MotorMixerRuleCollection = function () { let self = {}, data = [], + inactiveData = [], maxMotorCount = 8; self.setMotorCount = function (value) { @@ -16,7 +17,11 @@ var MotorMixerRuleCollection = function () { }; self.put = function (element) { - data.push(element); + if (data.length < self.getMotorCount()){ + data.push(element); + }else{ + inactiveData.push(element); //store the data for mixer_profile 2 + } }; self.get = function () { @@ -30,18 +35,25 @@ var MotorMixerRuleCollection = function () { self.flush = function () { data = []; + inactiveData = []; }; self.cleanup = function () { var tmpData = []; + var tmpInactiveData = []; data.forEach(function (element) { if (element.isUsed()) { tmpData.push(element); } }); - + inactiveData.forEach(function (element) { + if (element.isUsed()) { + tmpInactiveData.push(element); + } + }); data = tmpData; + inactiveData = tmpInactiveData; }; self.inflate = function () { @@ -55,7 +67,7 @@ var MotorMixerRuleCollection = function () { }; self.getNumberOfConfiguredMotors = function () { - return data.length; + return data.length > inactiveData.length ? data.length : inactiveData.length; }; return self; diff --git a/js/msp/MSPCodes.js b/js/msp/MSPCodes.js index 6c5f2be7..fe28c2a3 100644 --- a/js/msp/MSPCodes.js +++ b/js/msp/MSPCodes.js @@ -243,5 +243,7 @@ var MSPCodes = { MSP2_INAV_SET_RATE_DYNAMICS: 0x2061, MSP2_INAV_EZ_TUNE: 0x2070, - MSP2_INAV_EZ_TUNE_SET: 0x2071 + MSP2_INAV_EZ_TUNE_SET: 0x2071, + + MSP2_INAV_SELECT_MIXER_PROFILE: 0x2080 }; diff --git a/js/msp/MSPHelper.js b/js/msp/MSPHelper.js index cea0470c..3a1bed98 100644 --- a/js/msp/MSPHelper.js +++ b/js/msp/MSPHelper.js @@ -79,6 +79,8 @@ var mspHelper = (function (gui) { profile_byte = data.getUint8(offset++) CONFIG.profile = profile_byte & 0x0F; CONFIG.battery_profile = (profile_byte & 0xF0) >> 4; + profile_byte = data.getUint8(offset++) + CONFIG.mixer_profile = profile_byte & 0x0F; CONFIG.armingFlags = data.getUint32(offset, true); offset += 4; gui.updateStatusBar(); @@ -1454,7 +1456,7 @@ var mspHelper = (function (gui) { case MSPCodes.MSP2_INAV_MIXER: MIXER_CONFIG.yawMotorDirection = data.getInt8(0); MIXER_CONFIG.yawJumpPreventionLimit = data.getUint8(1, true); - MIXER_CONFIG.motorStopOnLow = data.getUint8(2, true); + MIXER_CONFIG.motorStopOnLow = data.getUint8(1, true); MIXER_CONFIG.platformType = data.getInt8(3); MIXER_CONFIG.hasFlaps = data.getInt8(4); MIXER_CONFIG.appliedMixerPreset = data.getInt16(5, true); diff --git a/js/servoMixerRuleCollection.js b/js/servoMixerRuleCollection.js index 8c3399a2..6f2b701c 100644 --- a/js/servoMixerRuleCollection.js +++ b/js/servoMixerRuleCollection.js @@ -5,6 +5,7 @@ let ServoMixerRuleCollection = function () { let self = {}, data = [], + inactiveData = [], maxServoCount = 16; self.setServoCount = function (value) { @@ -20,7 +21,11 @@ let ServoMixerRuleCollection = function () { } self.put = function (element) { - data.push(element); + if (data.length < self.getServoRulesCount()) { + data.push(element); + }else{ + inactiveData.push(element); //store the data for mixer_profile 2 + } }; self.get = function () { @@ -34,18 +39,24 @@ let ServoMixerRuleCollection = function () { self.flush = function () { data = []; + inactiveData = []; }; self.cleanup = function () { var tmpData = []; - + var tmpInactiveData = []; data.forEach(function (element) { if (element.isUsed()) { tmpData.push(element); } }); - + inactiveData.forEach(function (element) { + if (element.isUsed()) { + tmpInactiveData.push(element); + } + }); data = tmpData; + inactiveData = tmpInactiveData; }; self.inflate = function () { @@ -69,6 +80,15 @@ let ServoMixerRuleCollection = function () { } } } + for (let ruleIndex in inactiveData) { + if (inactiveData.hasOwnProperty(ruleIndex)) { + let rule = inactiveData[ruleIndex]; + + if (rule.getTarget() == servoId && rule.isUsed()) { + return true; + } + } + } return false; }; @@ -106,12 +126,17 @@ let ServoMixerRuleCollection = function () { out.push(rule.getTarget()); } } + for (let ruleIndex in inactiveData) { + if (inactiveData.hasOwnProperty(ruleIndex)) { + let rule = inactiveData[ruleIndex]; + out.push(rule.getTarget()); + } + } - let unique = [...new Set(out)]; - return unique.sort(function(a, b) { - return a-b; - }); + let minIndex = Math.min(...out); + let maxIndex = Math.max(...out); + return Array.from({ length: maxIndex - minIndex + 1 }, (_, index) => minIndex + index); } self.getNextUnusedIndex = function() { diff --git a/main.css b/main.css index 587088c4..01065766 100644 --- a/main.css +++ b/main.css @@ -1685,7 +1685,7 @@ dialog { color: white; font-size: 10px; margin-top: 20px; - width: 269px; + width: 410px; float: right; margin-right: 10px; line-height: 12px; @@ -1700,6 +1700,15 @@ dialog { } +#mixer_profile_change { + color: white; + margin-top: 16px; + width: 130px; + float: left; + margin-right: 10px; + line-height: 12px; +} + #profile_change { color: white; margin-top: 16px; diff --git a/main.html b/main.html index 1ae59453..92c89a58 100755 --- a/main.html +++ b/main.html @@ -87,6 +87,16 @@
+
+ +
+
+ + +
+
diff --git a/tabs/mixer.js b/tabs/mixer.js index 331d1475..8a997b59 100644 --- a/tabs/mixer.js +++ b/tabs/mixer.js @@ -170,8 +170,9 @@ TABS.mixer.initialize = function (callback, scrollPosition) { motors.push(outputPad); } else { let servo = servoRules.getServoMixRuleFromTarget(omIndex[1]); + if (servo == null) {continue;} let divID = "servoPreview" + omIndex[1]; - + switch (parseInt(servo.getInput())) { case INPUT_STABILIZED_PITCH: case STABILIZED_PITCH_POSITIVE: @@ -435,7 +436,10 @@ TABS.mixer.initialize = function (callback, scrollPosition) { $motorMixTableBody.append('\ \ \ - \ + \ + \ +
\ + \ \ \ \ @@ -446,9 +450,26 @@ TABS.mixer.initialize = function (callback, scrollPosition) { const $row = $motorMixTableBody.find('tr:last'); $row.find('.mix-rule-motor').html(index); - $row.find('.mix-rule-throttle').val(rule.getThrottle()).change(function () { - rule.setThrottle($(this).val()); - }); + const $throttleInput = $row.find('.mix-rule-throttle').val(rule.getThrottle()); + const $warningBox = $row.find('.throttle-warning-text'); + + // Function to update throttle and show/hide warning box + function updateThrottle() { + rule.setThrottle($throttleInput.val()); + // Change color if value exceeds 1 + if (parseFloat($throttleInput.val()) > 1 || parseFloat($throttleInput.val()) < 0) { + $throttleInput.css('background-color', 'orange'); + // Show warning box + $warningBox.show(); + } else { + $throttleInput.css('background-color', ''); // Reset to default + // Hide warning box + $warningBox.hide(); + } + } + updateThrottle(); + $throttleInput.change(updateThrottle); + $row.find('.mix-rule-roll').val(rule.getRoll()).change(function () { rule.setRoll($(this).val()); });