From 8b553192e454981e114edb7ddb448ba7db8902fe Mon Sep 17 00:00:00 2001 From: Woga65 Date: Mon, 7 Aug 2023 16:36:29 +0200 Subject: [PATCH 01/27] enable rc-channel remapping for the first eight rc-channels --- js/fc.js | 2 +- tabs/receiver.html | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/fc.js b/js/fc.js index b1040b0fb..49268d597 100644 --- a/js/fc.js +++ b/js/fc.js @@ -818,7 +818,7 @@ var FC = { } }, getRcMapLetters: function () { - return ['A', 'E', 'R', 'T']; + return ['A', 'E', 'R', 'T', '1', '2', '3', '4']; //woga65: rc-channel remapping }, isRcMapValid: function (val) { var strBuffer = val.split(''), diff --git a/tabs/receiver.html b/tabs/receiver.html index e71a64e32..d702c7725 100644 --- a/tabs/receiver.html +++ b/tabs/receiver.html @@ -22,9 +22,9 @@ From 419ebafa7a6cb65a3eaa41c2f3add6bb4dc99214 Mon Sep 17 00:00:00 2001 From: Woga65 Date: Mon, 7 Aug 2023 19:49:57 +0200 Subject: [PATCH 02/27] add collective pitch related stuff --- _locales/en/messages.json | 9 + js/fc.js | 13 +- js/model.js | 72 ++++++- js/msp/MSPHelper.js | 21 +- js/serial_backend.js | 1 + resources/motor_order/heli_bicopter.svg | 251 ++++++++++++++++++++++++ resources/motor_order/heli_quad_x.svg | 237 ++++++++++++++++++++++ src/css/tabs/receiver.css | 3 +- tabs/outputs.js | 4 + tabs/receiver.html | 4 +- tabs/receiver.js | 29 ++- 11 files changed, 621 insertions(+), 23 deletions(-) create mode 100644 resources/motor_order/heli_bicopter.svg create mode 100644 resources/motor_order/heli_quad_x.svg diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 740ad2e02..2be37d99c 100755 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -431,6 +431,9 @@ "fcInfoReceived": { "message": "Flight controller info, identifier: $1, version: $2" }, + "targetInfoReceived": { + "message": "Target variant: $1, is variable pitch: $2" + }, "notifications_app_just_updated_to_version": { "message": "Application just updated to version: $1" @@ -2455,6 +2458,12 @@ "controlAxisThrottle": { "message": "Throttle [T]" }, + "controlAxisCollective": { + "message": "Collective [C]" + }, + "controlGyroGain": { + "message": "Gyro gain [G]" + }, "controlAxisMotor": { "message": "Motor" }, diff --git a/js/fc.js b/js/fc.js index 49268d597..03f38b4fa 100644 --- a/js/fc.js +++ b/js/fc.js @@ -1,6 +1,11 @@ 'use strict'; // define all the global variables that are uses to hold FC state +const TARGET = { // woga65: info about the target variant + fullIdentifier: "", + isVariablePitch: false, +} + var CONFIG, LED_STRIP, LED_COLORS, @@ -818,7 +823,9 @@ var FC = { } }, getRcMapLetters: function () { - return ['A', 'E', 'R', 'T', '1', '2', '3', '4']; //woga65: rc-channel remapping + return TARGET.isVariablePitch //woga65: rc-channel remapping + ? ['A', 'E', 'R', 'T', '1', '2', 'C', 'G'] //if variable pitch, map collective + gyro gain + : ['A', 'E', 'R', 'T', '1', '2', '3', '4']; //else map AUX3 + AUX4 }, isRcMapValid: function (val) { var strBuffer = val.split(''), @@ -852,8 +859,8 @@ var FC = { 'RC Throttle', // 7 'RC Channel 5', // 8 'RC Channel 6', // 9 - 'RC Channel 7', // 10 - 'RC Channel 8', // 11 + TARGET.isVariablePitch ? 'RC Collective Pitch' : 'RC Channel 7', // 10 // woga65: channel naming for either + TARGET.isVariablePitch ? 'RC Gyro Gain' : 'RC Channel 8', // 11 // variable pitch or regular aircraft 'Gimbal Pitch', // 12 'Gimbal Roll', // 13 'Flaperon Mode', // 14 diff --git a/js/model.js b/js/model.js index 806140b14..92642619c 100644 --- a/js/model.js +++ b/js/model.js @@ -39,6 +39,8 @@ const INPUT_STABILIZED_ROLL = 0, STABILIZED_YAW_POSITIVE = 27; STABILIZED_YAW_NEGATIVE = 28; +const INPUT_RC_COLLECTIVE = INPUT_RC_AUX3; //woga65: default input mapping for collective pitch channel + const PLATFORM_MULTIROTOR = 0, PLATFORM_AIRPLANE = 1, @@ -596,6 +598,74 @@ const mixerList = [ servoMixer: [] }, // 16 + // woga65: ** variable pitch platforms ** + { + id: 35, + name: 'HeliQuad', + model: 'quad_x', + image: 'heli_quad_x', + enabled: true, + legacy: true, + platform: PLATFORM_HELICOPTER, + motorMixer: [ + new MotorMixRule(1.0, 0, 0, 0), // MOTOR OUT 1 + new MotorMixRule(1.0, 0, 0, 0), // MOTOR OUT 2 + ], + servoMixer: [ + new ServoMixRule(0, INPUT_STABILIZED_ROLL, -100, 0), //REAR_R + new ServoMixRule(0, INPUT_STABILIZED_PITCH, 100, 0), + new ServoMixRule(0, INPUT_STABILIZED_YAW, -100, 0), + new ServoMixRule(0, INPUT_RC_COLLECTIVE, 100, 0), + new ServoMixRule(1, INPUT_STABILIZED_ROLL, -100, 0), //FRONT_R + new ServoMixRule(1, INPUT_STABILIZED_PITCH, -100, 0), + new ServoMixRule(1, INPUT_STABILIZED_YAW, 100, 0), + new ServoMixRule(1, INPUT_RC_COLLECTIVE, 100, 0), + new ServoMixRule(2, INPUT_STABILIZED_ROLL, 100, 0), //REAR_L + new ServoMixRule(2, INPUT_STABILIZED_PITCH, 100, 0), + new ServoMixRule(2, INPUT_STABILIZED_YAW, 100, 0), + new ServoMixRule(2, INPUT_RC_COLLECTIVE, 100, 0), + new ServoMixRule(3, INPUT_STABILIZED_ROLL, 100, 0), //FRONT_L + new ServoMixRule(3, INPUT_STABILIZED_PITCH, -100, 0), + new ServoMixRule(3, INPUT_STABILIZED_YAW, -100, 0), + new ServoMixRule(3, INPUT_RC_COLLECTIVE, 100, 0), + ] + }, // 35 + { + id: 36, + name: 'Chinook style Bicopter 120deg', + model: 'custom', + image: 'heli_bicopter', + enabled: true, + legacy: true, + platform: PLATFORM_HELICOPTER, + motorMixer: [ + new MotorMixRule(1.0, 0, 0, 0), // MOTOR OUT 1 + new MotorMixRule(1.0, 0, 0, 0), // MOTOR OUT 2 + ], + servoMixer: [ + new ServoMixRule(0, INPUT_STABILIZED_ROLL, 100, 0), //REAR_L + new ServoMixRule(0, INPUT_STABILIZED_PITCH, 100, 0), + new ServoMixRule(0, INPUT_STABILIZED_YAW, -100, 0), + new ServoMixRule(0, INPUT_RC_COLLECTIVE, 100, 0), + new ServoMixRule(1, INPUT_STABILIZED_ROLL, -100, 0), //REAR_R + new ServoMixRule(1, INPUT_STABILIZED_PITCH, 100, 0), + new ServoMixRule(1, INPUT_STABILIZED_YAW, 100, 0), + new ServoMixRule(1, INPUT_RC_COLLECTIVE, 100, 0), + new ServoMixRule(2, INPUT_STABILIZED_PITCH, 100, 0), //REAR_PITCH + new ServoMixRule(2, INPUT_RC_COLLECTIVE, 100, 0), + new ServoMixRule(3, INPUT_STABILIZED_ROLL, 100, 0), //FRONT_L + new ServoMixRule(3, INPUT_STABILIZED_PITCH, -100, 0), + new ServoMixRule(3, INPUT_STABILIZED_YAW, 100, 0), + new ServoMixRule(3, INPUT_RC_COLLECTIVE, 100, 0), + new ServoMixRule(4, INPUT_STABILIZED_ROLL, -100, 0), //FRONT_R + new ServoMixRule(4, INPUT_STABILIZED_PITCH, -100, 0), + new ServoMixRule(4, INPUT_STABILIZED_YAW, -100, 0), + new ServoMixRule(4, INPUT_RC_COLLECTIVE, 100, 0), + new ServoMixRule(5, INPUT_STABILIZED_PITCH, -100, 0), //FRONT_PITCH + new ServoMixRule(5, INPUT_RC_COLLECTIVE, 100, 0), + ] + }, // 36 + // ** Other platforms ** { id: 31, @@ -683,7 +753,7 @@ const platformList = [ { id: 2, name: "Helicopter", - enabled: false, + enabled: true, //woga65: enable platform HELICOPTER flapsPossible: false }, { diff --git a/js/msp/MSPHelper.js b/js/msp/MSPHelper.js index 70458f65b..1fd302f9c 100644 --- a/js/msp/MSPHelper.js +++ b/js/msp/MSPHelper.js @@ -775,18 +775,23 @@ var mspHelper = (function (gui) { CONFIG.boardIdentifier = identifier; CONFIG.boardVersion = data.getUint16(offset, 1); offset += 2; + // woga65: Get full target name/identifier in any case. + // Also, determine whether target is variable pitch. if (semver.gt(CONFIG.flightControllerVersion, "4.1.0")) { CONFIG.osdUsed = data.getUint8(offset++); CONFIG.commCompatability = data.getUint8(offset++); - let targetNameLen = data.getUint8(offset++); - let targetName = ""; - targetNameLen += offset; - for (offset = offset; offset < targetNameLen; offset++) { - targetName += String.fromCharCode(data.getUint8(offset)); - } - CONFIG.target = targetName; + offset++; + } else { + offset += 3; + } + TARGET.fullIdentifier = ""; + for (let i = offset; i < data.byteLength; i++) { + TARGET.fullIdentifier += String.fromCharCode(data.getUint8(i)); + } + TARGET.isVariablePitch = TARGET.fullIdentifier.includes('_VP'); + if (semver.gt(CONFIG.flightControllerVersion, "4.1.0")) { //keep INAV's contributor's (MrD-RC) original + CONFIG.target = TARGET.fullIdentifier; //state of variables in case it's needed } - break; case MSPCodes.MSP_SET_CHANNEL_FORWARDING: diff --git a/js/serial_backend.js b/js/serial_backend.js index ec813bf38..ebc7c15e5 100755 --- a/js/serial_backend.js +++ b/js/serial_backend.js @@ -243,6 +243,7 @@ function onValidFirmware() googleAnalytics.sendEvent('Board', 'Using', CONFIG.boardIdentifier + ',' + CONFIG.boardVersion); GUI.log(chrome.i18n.getMessage('boardInfoReceived', [CONFIG.boardIdentifier, CONFIG.boardVersion])); + GUI.log(chrome.i18n.getMessage('targetInfoReceived', [TARGET.fullIdentifier, TARGET.isVariablePitch])); // woga65: MSP.send_message(MSPCodes.MSP_UID, false, false, function () { diff --git a/resources/motor_order/heli_bicopter.svg b/resources/motor_order/heli_bicopter.svg new file mode 100644 index 000000000..06a0eed08 --- /dev/null +++ b/resources/motor_order/heli_bicopter.svg @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + S0 + S1 + + + + + + + + + 1 + 2 + + + S2 + S5 + S3 + S4 + + + + + + diff --git a/resources/motor_order/heli_quad_x.svg b/resources/motor_order/heli_quad_x.svg new file mode 100644 index 000000000..122a2ef97 --- /dev/null +++ b/resources/motor_order/heli_quad_x.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + S2 + + + + S0 + + + + S3 + + + + S1 + + + diff --git a/src/css/tabs/receiver.css b/src/css/tabs/receiver.css index 92d54b561..0cb61c59f 100644 --- a/src/css/tabs/receiver.css +++ b/src/css/tabs/receiver.css @@ -43,7 +43,8 @@ } .tab-receiver .bars .meter { - width: calc(97% - 60px); + width: calc(97% - 70px); + padding-left: 10px; } .tab-receiver .bars .meter-bar { diff --git a/tabs/outputs.js b/tabs/outputs.js index aa9daf539..7fabd5085 100644 --- a/tabs/outputs.js +++ b/tabs/outputs.js @@ -79,8 +79,12 @@ TABS.outputs.initialize = function (callback) { finalize(); } + //woga65: if craft is variable pitch, output raw output values rather than percentages function getMotorOutputValue(value) { + if (TARGET.isVariablePitch) { + return value; + } if (!self.feature3DEnabled) { let valueNormalized = value - MISC.mincommand; let maxThrottleNormalized = MISC.maxthrottle - MISC.mincommand; diff --git a/tabs/receiver.html b/tabs/receiver.html index d702c7725..7283b3b5f 100644 --- a/tabs/receiver.html +++ b/tabs/receiver.html @@ -20,8 +20,8 @@
- + diff --git a/tabs/receiver.js b/tabs/receiver.js index 9f9b7fa5f..c6ccb5c6f 100644 --- a/tabs/receiver.js +++ b/tabs/receiver.js @@ -76,6 +76,16 @@ TABS.receiver.initialize = function (callback) { // translate to user-selected language localize(); + // woga65: if craft is variable pitch, default to + // collective and gyro gain rather than AUX channels + const rcMapElement = document.getElementById('rcmap_element'); + if (TARGET.isVariablePitch) { + rcMapElement.innerHTML = ` + + + `.trim(); + } + let $receiverMode = $('#receiver_type'), $serialWrapper = $('#serialrx_provider-wrapper'); @@ -120,21 +130,24 @@ TABS.receiver.initialize = function (callback) { $('.deadband input[name="deadband"]').val(RC_deadband.deadband); // generate bars + // woga65: including AUX- and/or variable pitch specific channel names var bar_names = [ chrome.i18n.getMessage('controlAxisRoll'), chrome.i18n.getMessage('controlAxisPitch'), chrome.i18n.getMessage('controlAxisYaw'), - chrome.i18n.getMessage('controlAxisThrottle') + chrome.i18n.getMessage('controlAxisThrottle'), + 'Aux 1 [1]', + 'Aux 2 [2]', + TARGET.isVariablePitch ? chrome.i18n.getMessage('controlAxisCollective') : 'Aux 3 [3]', + TARGET.isVariablePitch ? chrome.i18n.getMessage('controlGyroGain') : 'Aux 4 [4]', ], bar_container = $('.tab-receiver .bars'); for (var i = 0; i < RC.active_channels; i++) { var name; - if (i < bar_names.length) { - name = bar_names[i]; - } else { - name = chrome.i18n.getMessage("radioChannelShort") + (i + 1); - } + name = (i < bar_names.length && bar_names[i]) //woga65: + ? bar_names[i] + : chrome.i18n.getMessage("radioChannelShort") + (i + 1); bar_container.append('\
    \ @@ -304,8 +317,8 @@ TABS.receiver.initialize = function (callback) { googleAnalytics.sendEvent('Setting', 'RcMappingSave', rcMapValue); for (var i = 0; i < RC_MAP.length; i++) { - RC_MAP[i] = strBuffer.indexOf(FC.getRcMapLetters()[i]); - } + RC_MAP[i] = strBuffer.indexOf(FC.getRcMapLetters()[i]); // woga65: nothing to change here since variable pitch + } // firmware accepts collective pitch specific letters googleAnalytics.sendEvent('Setting', 'RcProtocol', $('#receiver_type option:selected').text() + ":" + $('#serialrx_provider option:selected').text()); From 2b49a195354296c1884235b995e77a4436b6dffb Mon Sep 17 00:00:00 2001 From: Woga65 Date: Mon, 7 Aug 2023 20:00:30 +0200 Subject: [PATCH 03/27] load variable pitch (pre)releases fron the online repository --- tabs/firmware_flasher.html | 3 ++- tabs/firmware_flasher.js | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tabs/firmware_flasher.html b/tabs/firmware_flasher.html index 1bbaed9bf..1cfff85d2 100755 --- a/tabs/firmware_flasher.html +++ b/tabs/firmware_flasher.html @@ -55,7 +55,8 @@ -