From 87d497715d4e48a00b11ca268b6b6cb4cc68cb9c Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Tue, 22 Sep 2020 15:37:13 +0200 Subject: [PATCH] Show the limit in motors graph --- js/flightlog.js | 74 ++++++++++++++++++++++++-------- js/flightlog_fielddefs.js | 8 ++++ js/flightlog_fields_presenter.js | 54 +++++++++++++++-------- js/flightlog_parser.js | 1 + js/graph_config.js | 12 +++++- 5 files changed, 112 insertions(+), 37 deletions(-) diff --git a/js/flightlog.js b/js/flightlog.js index 7d3c3887..5fbc6402 100644 --- a/js/flightlog.js +++ b/js/flightlog.js @@ -11,7 +11,7 @@ */ function FlightLog(logData) { var - ADDITIONAL_COMPUTED_FIELD_COUNT = 15, /** attitude + PID_SUM + PID_ERROR + RCCOMMAND_SCALED **/ + ADDITIONAL_COMPUTED_FIELD_COUNT = 23, /** attitude + PID_SUM + PID_ERROR + RCCOMMAND_SCALED + MOTOR_RAW **/ that = this, logIndex = false, @@ -232,6 +232,15 @@ function FlightLog(logData) { if (!(that.isFieldDisabled().GYRO || that.isFieldDisabled().PID)) { fieldNames.push("axisError[0]", "axisError[1]", "axisError[2]"); // Custom calculated error field } + if (!that.isFieldDisabled().MOTORS) { + for (let i = 0; i < MAX_MOTOR_NUMBER; i++) { + if (fieldNames.find(element => element === `motor[${i}]`)) { + fieldNames.push(`motorRaw[${i}]`); + } else { + break; + } + } + } fieldNameToIndex = {}; for (let i = 0; i < fieldNames.length; i++) { @@ -240,10 +249,10 @@ function FlightLog(logData) { } function estimateNumMotors() { - var count = 0; + let count = 0; - for (var j = 0; j < 8; j++) { - if (that.getMainFieldIndexByName("motor[" + j + "]") !== undefined) { + for (let j = 0; j < MAX_MOTOR_NUMBER; j++) { + if (that.getMainFieldIndexByName(`motor[${j}]`) !== undefined) { count++; } } @@ -515,23 +524,26 @@ function FlightLog(logData) { * sourceChunks and destChunks can be the same array. */ function injectComputedFields(sourceChunks, destChunks) { - var - gyroADC = [fieldNameToIndex["gyroADC[0]"], fieldNameToIndex["gyroADC[1]"], fieldNameToIndex["gyroADC[2]"]], - accSmooth = [fieldNameToIndex["accSmooth[0]"], fieldNameToIndex["accSmooth[1]"], fieldNameToIndex["accSmooth[2]"]], - magADC = [fieldNameToIndex["magADC[0]"], fieldNameToIndex["magADC[1]"], fieldNameToIndex["magADC[2]"]], - rcCommand = [fieldNameToIndex["rcCommand[0]"], fieldNameToIndex["rcCommand[1]"], fieldNameToIndex["rcCommand[2]"], fieldNameToIndex["rcCommand[3]"]], - setpoint = [fieldNameToIndex["setpoint[0]"], fieldNameToIndex["setpoint[1]"], fieldNameToIndex["setpoint[2]"], fieldNameToIndex["setpoint[3]"]], - flightModeFlagsIndex = fieldNameToIndex["flightModeFlags"], // This points to the flightmode data + const gyroADC = [fieldNameToIndex["gyroADC[0]"], fieldNameToIndex["gyroADC[1]"], fieldNameToIndex["gyroADC[2]"]]; + const accSmooth = [fieldNameToIndex["accSmooth[0]"], fieldNameToIndex["accSmooth[1]"], fieldNameToIndex["accSmooth[2]"]]; + const magADC = [fieldNameToIndex["magADC[0]"], fieldNameToIndex["magADC[1]"], fieldNameToIndex["magADC[2]"]]; + const rcCommand = [fieldNameToIndex["rcCommand[0]"], fieldNameToIndex["rcCommand[1]"], fieldNameToIndex["rcCommand[2]"], fieldNameToIndex["rcCommand[3]"]]; + const setpoint = [fieldNameToIndex["setpoint[0]"], fieldNameToIndex["setpoint[1]"], fieldNameToIndex["setpoint[2]"], fieldNameToIndex["setpoint[3]"]]; + + const flightModeFlagsIndex = fieldNameToIndex["flightModeFlags"]; // This points to the flightmode data - sourceChunkIndex, destChunkIndex, + const axisPID = [[fieldNameToIndex["axisP[0]"], fieldNameToIndex["axisI[0]"], fieldNameToIndex["axisD[0]"], fieldNameToIndex["axisF[0]"]], + [fieldNameToIndex["axisP[1]"], fieldNameToIndex["axisI[1]"], fieldNameToIndex["axisD[1]"], fieldNameToIndex["axisF[1]"]], + [fieldNameToIndex["axisP[2]"], fieldNameToIndex["axisI[2]"], fieldNameToIndex["axisD[2]"], fieldNameToIndex["axisF[2]"]]]; - sysConfig, - attitude, + const motor = [fieldNameToIndex["motor[0]"], fieldNameToIndex["motor[1]"], fieldNameToIndex["motor[2]"], fieldNameToIndex["motor[3]"], + fieldNameToIndex["motor[4]"], fieldNameToIndex["motor[5]"], fieldNameToIndex["motor[6]"], fieldNameToIndex["motor[7]"]]; - axisPID = [[fieldNameToIndex["axisP[0]"], fieldNameToIndex["axisI[0]"], fieldNameToIndex["axisD[0]"], fieldNameToIndex["axisF[0]"]], - [fieldNameToIndex["axisP[1]"], fieldNameToIndex["axisI[1]"], fieldNameToIndex["axisD[1]"], fieldNameToIndex["axisF[1]"]], - [fieldNameToIndex["axisP[2]"], fieldNameToIndex["axisI[2]"], fieldNameToIndex["axisD[2]"], fieldNameToIndex["axisF[2]"]]]; + let sourceChunkIndex; + let destChunkIndex; + let sysConfig; + let attitude; if (destChunks.length === 0) { return; @@ -658,6 +670,14 @@ function FlightLog(logData) { } } + // Duplicate the motor field to show the motor raw values + for (let motorNumber = 0; motorNumber < numMotors; motorNumber++) { + destFrame[fieldIndex++] = srcFrame[motor[motorNumber]]; + } + + // Remove empty fields at the end + destFrame.splice(fieldIndex); + } } } @@ -1145,9 +1165,27 @@ FlightLog.prototype.rcCommandRawToThrottle = function(value) { return Math.min(Math.max(((value - this.getSysConfig().minthrottle) / (this.getSysConfig().maxthrottle - this.getSysConfig().minthrottle)) * 100.0, 0.0),100.0); }; -FlightLog.prototype.rcMotorRawToPct = function(value) { +FlightLog.prototype.rcMotorRawToPctEffective = function(value) { + // Motor displayed as percentage return Math.min(Math.max(((value - this.getSysConfig().motorOutput[0]) / (this.getSysConfig().motorOutput[1] - this.getSysConfig().motorOutput[0])) * 100.0, 0.0),100.0); + +} + +FlightLog.prototype.rcMotorRawToPctPhysical = function(value) { + + // Motor displayed as percentage + let motorPct; + if (this.getSysConfig().fast_pwm_protocol < FAST_PROTOCOL.indexOf('DSHOT150')) { + // Analog protocol + const ANALOG_RANGE = this.getSysConfig().maxthrottle - ANALOG_MIN_VALUE; + motorPct = ((value - ANALOG_MIN_VALUE) / ANALOG_RANGE) * 100; + } else { + // Digital protocol + motorPct = ((value - DSHOT_MIN_VALUE) / DSHOT_RANGE) * 100; + } + return Math.min(Math.max(motorPct, 0.0), 100.0); + }; FlightLog.prototype.getPIDPercentage = function(value) { diff --git a/js/flightlog_fielddefs.js b/js/flightlog_fielddefs.js index a7d05990..686ff59e 100644 --- a/js/flightlog_fielddefs.js +++ b/js/flightlog_fielddefs.js @@ -10,6 +10,14 @@ function makeReadOnly(x) { return x; } +// Some constants used at different places +const MAX_MOTOR_NUMBER = 8; +const DSHOT_MIN_VALUE = 48; +const DSHOT_MAX_VALUE = 2047; +const DSHOT_RANGE = DSHOT_MAX_VALUE - DSHOT_MIN_VALUE; +const ANALOG_MIN_VALUE = 1000; + +// Fields definitions for lists var FlightLogEvent = makeReadOnly({ SYNC_BEEP: 0, diff --git a/js/flightlog_fields_presenter.js b/js/flightlog_fields_presenter.js index 6079e3f8..b10d1912 100644 --- a/js/flightlog_fields_presenter.js +++ b/js/flightlog_fields_presenter.js @@ -4,7 +4,7 @@ function FlightLogFieldPresenter() { } (function() { - var FRIENDLY_FIELD_NAMES = { + const FRIENDLY_FIELD_NAMES = { 'axisP[all]': 'PID P', 'axisP[0]': 'PID P [roll]', @@ -58,15 +58,25 @@ function FlightLogFieldPresenter() { //End-users prefer 1-based indexing 'motor[all]': 'Motors', - 'motor[0]': 'Motor [1]', - 'motor[1]': 'Motor [2]', - 'motor[2]': 'Motor [3]', + 'motor[0]': 'Motor [1]', + 'motor[1]': 'Motor [2]', + 'motor[2]': 'Motor [3]', 'motor[3]': 'Motor [4]', - 'motor[4]': 'Motor [5]', - 'motor[5]': 'Motor [6]', - 'motor[6]': 'Motor [7]', + 'motor[4]': 'Motor [5]', + 'motor[5]': 'Motor [6]', + 'motor[6]': 'Motor [7]', 'motor[7]': 'Motor [8]', + 'motorRaw[all]': 'Motors Raw', + 'motorRaw[0]': 'Motor Raw [1]', + 'motorRaw[1]': 'Motor Raw [2]', + 'motorRaw[2]': 'Motor Raw [3]', + 'motorRaw[3]': 'Motor Raw [4]', + 'motorRaw[4]': 'Motor Raw [5]', + 'motorRaw[5]': 'Motor Raw [6]', + 'motorRaw[6]': 'Motor Raw [7]', + 'motorRaw[7]': 'Motor Raw [8]', + 'servo[all]': 'Servos', 'servo[5]': 'Servo Tail', @@ -96,7 +106,7 @@ function FlightLogFieldPresenter() { 'rxFlightChannelsValid': 'RX Flight Ch. Valid', 'rssi': 'RSSI', }; - + var DEBUG_FRIENDLY_FIELD_NAMES = { 'NONE' : { 'debug[all]':'Debug [all]', @@ -502,16 +512,26 @@ function FlightLogFieldPresenter() { return (value + 1500).toFixed(0) + " us"; case 'rcCommand[3]': return value.toFixed(0) + " us"; - + case 'motor[0]': - case 'motor[1]': - case 'motor[2]': - case 'motor[3]': - case 'motor[4]': - case 'motor[5]': - case 'motor[6]': - case 'motor[7]': - return Math.round(flightLog.rcMotorRawToPct(value)) + " %"; + case 'motor[1]': + case 'motor[2]': + case 'motor[3]': + case 'motor[4]': + case 'motor[5]': + case 'motor[6]': + case 'motor[7]': + return `${Math.round(flightLog.rcMotorRawToPctEffective(value))} %`; + + case 'motorRaw[0]': + case 'motorRaw[1]': + case 'motorRaw[2]': + case 'motorRaw[3]': + case 'motorRaw[4]': + case 'motorRaw[5]': + case 'motorRaw[6]': + case 'motorRaw[7]': + return `${Math.round(flightLog.rcMotorRawToPctPhysical(value))} % (${value})`; case 'rcCommands[0]': case 'rcCommands[1]': diff --git a/js/flightlog_parser.js b/js/flightlog_parser.js index d22e4d01..68d6dc68 100644 --- a/js/flightlog_parser.js +++ b/js/flightlog_parser.js @@ -621,6 +621,7 @@ var FlightLogParser = function(logData) { case "rates_type": case "vbat_sag_compensation": case "fields_disabled_mask": + case "motor_pwm_protocol": that.sysConfig[fieldName] = parseInt(fieldValue, 10); break; case "rc_expo": diff --git a/js/graph_config.js b/js/graph_config.js index def6cd8b..d6a3c599 100644 --- a/js/graph_config.js +++ b/js/graph_config.js @@ -174,7 +174,7 @@ GraphConfig.load = function(config) { (function() { GraphConfig.getDefaultSmoothingForField = function(flightLog, fieldName) { try{ - if (fieldName.match(/^motor\[/)) { + if (fieldName.match(/^motor(Raw)?\[/)) { return 5000; } else if (fieldName.match(/^servo\[/)) { return 5000; @@ -264,7 +264,15 @@ GraphConfig.load = function(config) { offset: -(sysConfig.motorOutput[1] + sysConfig.motorOutput[0]) / 2, power: 1.0, inputRange: (sysConfig.motorOutput[1] - sysConfig.motorOutput[0]) / 2, - outputRange: 1.0 + outputRange: 1.0, + }; + } else if (fieldName.match(/^motorRaw\[/)) { + return { + offset: sysConfig.fast_pwm_protocol < FAST_PROTOCOL.indexOf('DSHOT150') ? + -(ANALOG_MIN_VALUE + (sysConfig.maxthrottle - ANALOG_MIN_VALUE) / 2) : -(DSHOT_MIN_VALUE + DSHOT_RANGE / 2), + power: 1.0, + inputRange: sysConfig.fast_pwm_protocol < FAST_PROTOCOL.indexOf('DSHOT150') ? (sysConfig.maxthrottle - ANALOG_MIN_VALUE) / 2 : DSHOT_RANGE / 2, + outputRange: 1.0, }; } else if (fieldName.match(/^servo\[/)) { return {