mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-15 04:15:32 +03:00
Merge pull request #2296 from limonspb/esc_dshot_reverse
This commit is contained in:
commit
d5d0146af7
20 changed files with 1255 additions and 103 deletions
|
@ -2586,6 +2586,82 @@
|
||||||
"message": "Start over"
|
"message": "Start over"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"escDshotDirectionDialog-Title": {
|
||||||
|
"message": "Motor Direction - <strong class=\"message-negative-italic\">Warning: Ensure props are removed!</strong>"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-SelectMotor": {
|
||||||
|
"message": "Select one or all motors"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-SelectMotorSafety": {
|
||||||
|
"message": "Motors will spin when selected!"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-RiskNotice": {
|
||||||
|
"message": "<strong>Safety notice</strong><br /><strong class=\"message-negative-italic\">Remove all propellers to prevent injury!</strong><br />The motors will <strong>spin up</strong> immediately when selected!"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-UnderstandRisks": {
|
||||||
|
"message": "<strong>I understand the risks</strong>,<br />all propellers are removed."
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-InformationNotice": {
|
||||||
|
"message": "<strong>Information notice</strong><br />To change the motor directions, the battery must be plugged in and the correct ESC protocol must be set up in the $t(tabConfiguration.message) tab. Note that not all Dshot ESCs will work with this dialog. Check your ESC firmware."
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-NormalInformationNotice": {
|
||||||
|
"message": "Set motor spin direction by selecting and spinning each motor individually."
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-WizardInformationNotice": {
|
||||||
|
"message": "Resets all motor spin directions, then allows the user to choose which to reverse."
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-Open": {
|
||||||
|
"message": "Motor direction"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-CommandNormal": {
|
||||||
|
"message": "Normal"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-CommandReverse": {
|
||||||
|
"message": "Reverse"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-CommandSpin": {
|
||||||
|
"message": "Test motor"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-ReleaseButtonToStop": {
|
||||||
|
"message": "Release button to stop"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-ReleaseToStop": {
|
||||||
|
"message": "Release to stop"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-Start": {
|
||||||
|
"message": "Individually"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-StartWizard": {
|
||||||
|
"message": "Wizard"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-SetDirectionHint": {
|
||||||
|
"message": "Change direction of selected motor(s)"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-SetDirectionHintSafety": {
|
||||||
|
"message": "Motors will spin when setting the direction!"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-WrongProtocolText": {
|
||||||
|
"message": "Feature works with DSHOT ESCs only.<br />Verify that your ESC (electric speed controller) supports DSHOT protocol and change it on $t(tabConfiguration.message) tab."
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-WrongMixerText": {
|
||||||
|
"message": "Number of motors is 0.<br />Verify the current Mixer on $t(tabConfiguration.message) tab or setup a custom one through CLI. Refer to this <a href=\"https://github.com/betaflight/betaflight/blob/master/docs/Mixer.md\" target=\"_blank\" rel=\"noopener noreferrer\">Wiki page</a>."
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-WrongFirmwareText": {
|
||||||
|
"message": "Update the firmware.<br /> Make sure you are using the latest firmware: Betaflight 4.3 or newer."
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-WizardActionHint": {
|
||||||
|
"message": "Click on motor numbers individually to change spin direction"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-WizardActionHintSecondLine": {
|
||||||
|
"message": "Verify all motors are spinning correctly"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-SpinWizard": {
|
||||||
|
"message": "Start / spin motors"
|
||||||
|
},
|
||||||
|
"escDshotDirectionDialog-StopWizard": {
|
||||||
|
"message": "Stop motors"
|
||||||
|
},
|
||||||
|
|
||||||
"sensorsInfo": {
|
"sensorsInfo": {
|
||||||
"message": "Keep in mind that using fast update periods and rendering multiple graphs at the same time is resource heavy and will burn your battery quicker if you use a laptop.<br />We recommend to only render graphs for sensors you are interested in while using reasonable update periods."
|
"message": "Keep in mind that using fast update periods and rendering multiple graphs at the same time is resource heavy and will burn your battery quicker if you use a laptop.<br />We recommend to only render graphs for sensors you are interested in while using reasonable update periods."
|
||||||
},
|
},
|
||||||
|
|
66
src/components/EscDshotDirection/Body.html
Normal file
66
src/components/EscDshotDirection/Body.html
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<div class="escDshotDirection-Component">
|
||||||
|
<h3 i18n="escDshotDirectionDialog-Title" class="escDshotDirection-ComponentHeader"></h3>
|
||||||
|
<div class="componentContent" id="escDshotDirectionDialog-ConfigErrors">
|
||||||
|
<div class="escDshotDirectionErrorTextBlock" id="escDshotDirectionDialog-WrongProtocol" i18n="escDshotDirectionDialog-WrongProtocolText"></div>
|
||||||
|
<div class="escDshotDirectionErrorTextBlock" id="escDshotDirectionDialog-WrongMixer" i18n="escDshotDirectionDialog-WrongMixerText"></div>
|
||||||
|
<div class="escDshotDirectionErrorTextBlock" id="escDshotDirectionDialog-WrongFirmware" i18n="escDshotDirectionDialog-WrongFirmwareText"></div>
|
||||||
|
</div>
|
||||||
|
<div class="componentContent" id="escDshotDirectionDialog-MainContent">
|
||||||
|
<div id="escDshotDirectionDialog-MixerPreview" class="grey">
|
||||||
|
<img id="escDshotDirectionDialog-MixerPreviewImg" alt="" src="./resources/motor_order/custom.svg" />
|
||||||
|
</div>
|
||||||
|
<div id="escDshotDirectionDialog-NormalDialog" class="display-contents">
|
||||||
|
<h4 id="escDshotDirectionDialog-ActionHint" i18n="escDshotDirectionDialog-SelectMotor"></h4>
|
||||||
|
<h4 id="escDshotDirectionDialog-ActionHintSafety" i18n="escDshotDirectionDialog-SelectMotorSafety"></h4>
|
||||||
|
<div id="escDshotDirectionDialog-SelectMotorButtonsWrapper">
|
||||||
|
</div>
|
||||||
|
<div id = "escDshotDirectionDialog-SecondActionBlock" class="display-contents">
|
||||||
|
<h4 id="escDshotDirectionDialog-SecondHint" i18n="escDshotDirectionDialog-SetDirectionHint"></h4>
|
||||||
|
<h4 id="escDshotDirectionDialog-SecondHintSafety" i18n="escDshotDirectionDialog-SetDirectionHintSafety"></h4>
|
||||||
|
<div id="escDshotDirectionDialog-CommandsWrapper">
|
||||||
|
<a href="#" id="escDshotDirectionDialog-RotationNormal" class="regular-button" i18n="escDshotDirectionDialog-CommandNormal"></a>
|
||||||
|
<a href="#" id="escDshotDirectionDialog-RotationReverse" class="regular-button" i18n="escDshotDirectionDialog-CommandReverse"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="escDshotDirectionDialog-WizardDialog" class="display-contents">
|
||||||
|
<a href="#" id="escDshotDirectionDialog-SpinWizard" class="regular-button" i18n="escDshotDirectionDialog-SpinWizard"></a>
|
||||||
|
<div id="escDshotDirectionDialog-SpinningWizard" class="display-contents">
|
||||||
|
<h4 id="escDshotDirectionDialog-WizardActionHint" i18n="escDshotDirectionDialog-WizardActionHint"></h4>
|
||||||
|
<h4 id="escDshotDirectionDialog-WizardActionHintSecondLine" i18n="escDshotDirectionDialog-WizardActionHintSecondLine"></h4>
|
||||||
|
<div id="escDshotDirectionDialog-WizardMotorButtons">
|
||||||
|
</div>
|
||||||
|
<a href="#" id="escDshotDirectionDialog-StopWizard" class="regular-button" i18n="escDshotDirectionDialog-StopWizard"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="componentContent" id="escDshotDirectionDialog-Warning">
|
||||||
|
<div>
|
||||||
|
<p class="escDshotDirectionDialog-RiskNoticeText" i18n="escDshotDirectionDialog-RiskNotice"></p>
|
||||||
|
<div class="escDshotDirectionToggleParentContainer">
|
||||||
|
<div class="escDshotDirectionToggleNarrow">
|
||||||
|
<input id="escDshotDirectionDialog-safetyCheckbox" type="checkbox" class="toggle"/>
|
||||||
|
</div>
|
||||||
|
<div class="escDshotDirectionDialog-ToggleWide">
|
||||||
|
<span class="motorsEnableTestMode escDshotDirectionDialog-RiskNoticeText" i18n="escDshotDirectionDialog-UnderstandRisks"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="escDshotDirectionDialog-InformationNotice" i18n="escDshotDirectionDialog-InformationNotice"></div>
|
||||||
|
|
||||||
|
<div id="escDshotDirectionDialog-StartWizardBlock" class="escDshotDirectionDialog-StartBlock">
|
||||||
|
<div class="escDshotDirectionDialog-Buttons">
|
||||||
|
<a href="#" id="escDshotDirectionDialog-StartWizard" class="regular-button escDshotDirectionDialog-StartButton" i18n="escDshotDirectionDialog-StartWizard"></a>
|
||||||
|
</div>
|
||||||
|
<div class="escDshotDirectionDialog-Description" i18n="escDshotDirectionDialog-WizardInformationNotice"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="escDshotDirectionDialog-StartNormalBlock" class="escDshotDirectionDialog-StartBlock">
|
||||||
|
<div class="escDshotDirectionDialog-Buttons">
|
||||||
|
<a href="#" id="escDshotDirectionDialog-Start" class="regular-button escDshotDirectionDialog-StartButton" i18n="escDshotDirectionDialog-Start"></a>
|
||||||
|
</div>
|
||||||
|
<div class="escDshotDirectionDialog-Description" i18n="escDshotDirectionDialog-NormalInformationNotice"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
67
src/components/EscDshotDirection/EscDshotCommandQueue.js
Normal file
67
src/components/EscDshotDirection/EscDshotCommandQueue.js
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class EscDshotCommandQueue
|
||||||
|
{
|
||||||
|
constructor (intervalMs)
|
||||||
|
{
|
||||||
|
this._intervalId = null;
|
||||||
|
this._interval = intervalMs;
|
||||||
|
this._queue = [];
|
||||||
|
this._purging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pushCommand(command, buffer)
|
||||||
|
{
|
||||||
|
this._queue.push([command, buffer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pushPause(milliseconds)
|
||||||
|
{
|
||||||
|
const counter = Math.ceil(milliseconds / this._interval);
|
||||||
|
|
||||||
|
for (let i = 0; i < counter; i++) {
|
||||||
|
this.pushCommand(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start()
|
||||||
|
{
|
||||||
|
if (null === this._intervalId) {
|
||||||
|
this._intervalId = setInterval(
|
||||||
|
() => { this._checkQueue(); },
|
||||||
|
this._interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop()
|
||||||
|
{
|
||||||
|
if(null !== this._intervalId) {
|
||||||
|
clearInterval(this._intervalId);
|
||||||
|
this._intervalId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stopWhenEmpty()
|
||||||
|
{
|
||||||
|
this._purging = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear()
|
||||||
|
{
|
||||||
|
this._queue = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkQueue()
|
||||||
|
{
|
||||||
|
if (0 !== this._queue.length) {
|
||||||
|
const command = this._queue.shift();
|
||||||
|
|
||||||
|
if (null !== command[0]) {
|
||||||
|
MSP.send_message(command[0], command[1]);
|
||||||
|
}
|
||||||
|
} else if (this._purging) {
|
||||||
|
this._purging = false;
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
383
src/components/EscDshotDirection/EscDshotDirectionComponent.js
Normal file
383
src/components/EscDshotDirection/EscDshotDirectionComponent.js
Normal file
|
@ -0,0 +1,383 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class EscDshotDirectionComponent
|
||||||
|
{
|
||||||
|
constructor(contentDiv, onLoadedCallback, motorConfig)
|
||||||
|
{
|
||||||
|
this._buttonTimeoutMs = 400;
|
||||||
|
const motorDriverQueueIntervalMs = 100;
|
||||||
|
const motorDriverStopMotorsPauseMs = 400;
|
||||||
|
|
||||||
|
this._motorDriver = new EscDshotDirectionMotorDriver(motorConfig,
|
||||||
|
motorDriverQueueIntervalMs, motorDriverStopMotorsPauseMs);
|
||||||
|
this._escProtocolIsDshot = motorConfig.escProtocolIsDshot;
|
||||||
|
this._numberOfMotors = motorConfig.numberOfMotors;
|
||||||
|
this._contentDiv = contentDiv;
|
||||||
|
this._onLoadedCallback = onLoadedCallback;
|
||||||
|
this._currentSpinningMotor = -1;
|
||||||
|
this._selectedMotor = -1;
|
||||||
|
this._motorIsSpinning = false;
|
||||||
|
this._allMotorsAreSpinning = false;
|
||||||
|
this._spinDirectionToggleIsActive = true;
|
||||||
|
this._activationButtonTimeoutId = null;
|
||||||
|
|
||||||
|
this._contentDiv.load("./components/EscDshotDirection/Body.html", () =>
|
||||||
|
{
|
||||||
|
this._initializeDialog();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static get PUSHED_BUTTON_CLASS() { return "pushed"; }
|
||||||
|
static get HIGHLIGHTED_BUTTON_CLASS() { return "highlighted"; }
|
||||||
|
static get RED_TEXT_CLASS() { return "red-text"; }
|
||||||
|
|
||||||
|
_readDom()
|
||||||
|
{
|
||||||
|
this._domAgreeSafetyCheckBox = $("#escDshotDirectionDialog-safetyCheckbox");
|
||||||
|
this._domStartButton = $("#escDshotDirectionDialog-Start");
|
||||||
|
this._domStartWizardButton = $("#escDshotDirectionDialog-StartWizard");
|
||||||
|
this._domMainContentBlock = $("#escDshotDirectionDialog-MainContent");
|
||||||
|
this._domWarningContentBlock = $("#escDshotDirectionDialog-Warning");
|
||||||
|
this._domMixerImg = $("#escDshotDirectionDialog-MixerPreviewImg");
|
||||||
|
this._domMotorButtonsBlock = $("#escDshotDirectionDialog-SelectMotorButtonsWrapper");
|
||||||
|
this._domSpinDirectionWrapper = $("#escDshotDirectionDialog-CommandsWrapper");
|
||||||
|
this._domActionHint = $("#escDshotDirectionDialog-ActionHint");
|
||||||
|
this._domSpinNormalButton = $("#escDshotDirectionDialog-RotationNormal");
|
||||||
|
this._domSpinReverseButton = $("#escDshotDirectionDialog-RotationReverse");
|
||||||
|
this._domSecondHint = $("#escDshotDirectionDialog-SecondHint");
|
||||||
|
this._domSecondActionDiv = $("#escDshotDirectionDialog-SecondActionBlock");
|
||||||
|
this._domConfigErrors = $("#escDshotDirectionDialog-ConfigErrors");
|
||||||
|
this._domWrongProtocolMessage = $("#escDshotDirectionDialog-WrongProtocol");
|
||||||
|
this._domWrongMixerMessage = $("#escDshotDirectionDialog-WrongMixer");
|
||||||
|
this._domWrongFirmwareMessage = $("#escDshotDirectionDialog-WrongFirmware");
|
||||||
|
this._domWizardBlock = $("#escDshotDirectionDialog-WizardDialog");
|
||||||
|
this._domNormalDialogBlock = $("#escDshotDirectionDialog-NormalDialog");
|
||||||
|
this._domSpinningWizard = $("#escDshotDirectionDialog-SpinningWizard");
|
||||||
|
this._domSpinWizardButton = $("#escDshotDirectionDialog-SpinWizard");
|
||||||
|
this._domStopWizardButton = $("#escDshotDirectionDialog-StopWizard");
|
||||||
|
this._domWizardMotorButtonsBlock = $("#escDshotDirectionDialog-WizardMotorButtons");
|
||||||
|
this._domStartWizardBlock = $("#escDshotDirectionDialog-StartWizardBlock");
|
||||||
|
this._domStartNormalBlock = $("#escDshotDirectionDialog-StartNormalBlock");
|
||||||
|
|
||||||
|
this._topHintText = i18n.getMessage("escDshotDirectionDialog-SelectMotor");
|
||||||
|
this._releaseToStopText = i18n.getMessage("escDshotDirectionDialog-ReleaseToStop");
|
||||||
|
this._releaseButtonToStopText = i18n.getMessage("escDshotDirectionDialog-ReleaseButtonToStop");
|
||||||
|
this._normalText = i18n.getMessage("escDshotDirectionDialog-CommandNormal");
|
||||||
|
this._reverseText = i18n.getMessage("escDshotDirectionDialog-CommandReverse");
|
||||||
|
this._secondHintText = i18n.getMessage("escDshotDirectionDialog-SetDirectionHint");
|
||||||
|
}
|
||||||
|
|
||||||
|
_initializeDialog()
|
||||||
|
{
|
||||||
|
this._readDom();
|
||||||
|
this._createMotorButtons();
|
||||||
|
this._createWizardMotorButtons();
|
||||||
|
this._domSecondActionDiv.toggle(false);
|
||||||
|
i18n.localizePage();
|
||||||
|
|
||||||
|
this._resetGui();
|
||||||
|
|
||||||
|
this._domAgreeSafetyCheckBox.on("change", () => {
|
||||||
|
const enabled = this._domAgreeSafetyCheckBox.is(':checked');
|
||||||
|
this._domStartNormalBlock.toggle(enabled);
|
||||||
|
this._domStartWizardBlock.toggle(enabled);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._domStartButton.on("click", () => {
|
||||||
|
this._onStartButtonClicked();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._domStartWizardButton.on("click", () => {
|
||||||
|
this._onStartWizardButtonClicked();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._domSpinWizardButton.on("click", () => {
|
||||||
|
this._onSpinWizardButtonClicked();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._domStopWizardButton.on("click", () => {
|
||||||
|
this._onStopWizardButtonClicked();
|
||||||
|
});
|
||||||
|
|
||||||
|
const imgSrc = CommonUtils.GetMixerImageSrc(FC.MIXER_CONFIG.mixer, FC.MIXER_CONFIG.reverseMotorDir, FC.CONFIG.apiVersion);
|
||||||
|
this._domMixerImg.attr('src', imgSrc);
|
||||||
|
|
||||||
|
this._onLoadedCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
_activateNormalReverseButtons(timeoutMs)
|
||||||
|
{
|
||||||
|
this._activationButtonTimeoutId = setTimeout(() => {
|
||||||
|
this._subscribeDirectionSpinButton(this._domSpinNormalButton,
|
||||||
|
DshotCommand.dshotCommands_e.DSHOT_CMD_SPIN_DIRECTION_1, this._normalText);
|
||||||
|
this._subscribeDirectionSpinButton(this._domSpinReverseButton,
|
||||||
|
DshotCommand.dshotCommands_e.DSHOT_CMD_SPIN_DIRECTION_2, this._reverseText);
|
||||||
|
}, timeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
_deactivateNormalReverseButtons()
|
||||||
|
{
|
||||||
|
if (null !== this._activationButtonTimeoutId)
|
||||||
|
{
|
||||||
|
clearTimeout(this._activationButtonTimeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._domSpinNormalButton.off();
|
||||||
|
this._domSpinReverseButton.off();
|
||||||
|
}
|
||||||
|
|
||||||
|
_subscribeDirectionSpinButton(button, direction, buttonText)
|
||||||
|
{
|
||||||
|
button.on("mousedown touchstart", () => {
|
||||||
|
this._sendCurrentEscSpinDirection(direction);
|
||||||
|
this._motorIsSpinning = true;
|
||||||
|
button.text(this._releaseToStopText);
|
||||||
|
button.addClass(EscDshotDirectionComponent.HIGHLIGHTED_BUTTON_CLASS);
|
||||||
|
this._motorDriver.spinMotor(this._selectedMotor);
|
||||||
|
this._domSecondHint.html(this._releaseButtonToStopText);
|
||||||
|
this._domSecondHint.addClass(EscDshotDirectionComponent.RED_TEXT_CLASS);
|
||||||
|
});
|
||||||
|
|
||||||
|
button.on("mouseup mouseout touchend", () => {
|
||||||
|
if (this._motorIsSpinning) {
|
||||||
|
button.text(buttonText);
|
||||||
|
this._motorIsSpinning = false;
|
||||||
|
button.removeClass(EscDshotDirectionComponent.HIGHLIGHTED_BUTTON_CLASS);
|
||||||
|
this._motorDriver.stopAllMotors();
|
||||||
|
this._domSecondHint.text(this._secondHintText);
|
||||||
|
this._domSecondHint.removeClass(EscDshotDirectionComponent.RED_TEXT_CLASS);
|
||||||
|
|
||||||
|
this._deactivateNormalReverseButtons();
|
||||||
|
this._activateNormalReverseButtons(this._buttonTimeoutMs);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendCurrentEscSpinDirection(direction)
|
||||||
|
{
|
||||||
|
this._motorDriver.setEscSpinDirection(this._selectedMotor, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createMotorButtons()
|
||||||
|
{
|
||||||
|
this._motorButtons = {};
|
||||||
|
|
||||||
|
for (let i = 0; i < this._numberOfMotors; i++) {
|
||||||
|
this._addMotorButton(i + 1, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._addMotorButton("All", DshotCommand.ALL_MOTORS);
|
||||||
|
}
|
||||||
|
|
||||||
|
_addMotorButton(buttonText, motorIndex)
|
||||||
|
{
|
||||||
|
const button = $(`<a href="#" class="regular-button ${EscDshotDirectionComponent.PUSHED_BUTTON_CLASS}"></a>`).text(buttonText);
|
||||||
|
this._domMotorButtonsBlock.append(button);
|
||||||
|
this._motorButtons[motorIndex] = button;
|
||||||
|
|
||||||
|
button.on("mousedown touchstart", () => {
|
||||||
|
this._domSecondActionDiv.toggle(true);
|
||||||
|
this._motorIsSpinning = true;
|
||||||
|
this._domActionHint.html(this._releaseButtonToStopText);
|
||||||
|
this._domActionHint.addClass(EscDshotDirectionComponent.RED_TEXT_CLASS);
|
||||||
|
this._changeSelectedMotor(motorIndex);
|
||||||
|
button.addClass(EscDshotDirectionComponent.HIGHLIGHTED_BUTTON_CLASS);
|
||||||
|
this._motorDriver.spinMotor(this._selectedMotor);
|
||||||
|
});
|
||||||
|
|
||||||
|
button.on("mouseup mouseout touchend", () => {
|
||||||
|
if (this._motorIsSpinning) {
|
||||||
|
this._domActionHint.html(this._topHintText);
|
||||||
|
this._domActionHint.removeClass(EscDshotDirectionComponent.RED_TEXT_CLASS);
|
||||||
|
this._motorIsSpinning = false;
|
||||||
|
button.removeClass(EscDshotDirectionComponent.HIGHLIGHTED_BUTTON_CLASS);
|
||||||
|
this._motorDriver.stopAllMotors();
|
||||||
|
|
||||||
|
this._deactivateNormalReverseButtons();
|
||||||
|
this._activateNormalReverseButtons(this._buttonTimeoutMs);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_createWizardMotorButtons()
|
||||||
|
{
|
||||||
|
this._wizardMotorButtons = {};
|
||||||
|
|
||||||
|
for (let i = 0; i < this._numberOfMotors; i++) {
|
||||||
|
this._addWizardMotorButton(i + 1, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_activateWizardMotorButtons(timeoutMs)
|
||||||
|
{
|
||||||
|
this._activationButtonTimeoutId = setTimeout(() => {
|
||||||
|
for (let i = 0; i < this._numberOfMotors; i++) {
|
||||||
|
this._activateWizardMotorButton(i);
|
||||||
|
}
|
||||||
|
}, timeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
_deactivateWizardMotorButtons()
|
||||||
|
{
|
||||||
|
if (null !== this._activationButtonTimeoutId)
|
||||||
|
{
|
||||||
|
clearTimeout(this._activationButtonTimeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this._numberOfMotors; i++) {
|
||||||
|
const button = this._wizardMotorButtons[i];
|
||||||
|
button.off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_addWizardMotorButton(buttonText, motorIndex)
|
||||||
|
{
|
||||||
|
const button = $(`<a href="#" class="regular-button"></a>`).text(buttonText);
|
||||||
|
this._domWizardMotorButtonsBlock.append(button);
|
||||||
|
this._wizardMotorButtons[motorIndex] = button;
|
||||||
|
}
|
||||||
|
|
||||||
|
_activateWizardMotorButton(motorIndex)
|
||||||
|
{
|
||||||
|
const button = this._wizardMotorButtons[motorIndex];
|
||||||
|
|
||||||
|
button.on("click", () => {
|
||||||
|
this._wizardMotorButtonClick(button, motorIndex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_wizardMotorButtonClick(button, motorIndex)
|
||||||
|
{
|
||||||
|
this._deactivateWizardMotorButtons();
|
||||||
|
const currentlyDown = button.hasClass(EscDshotDirectionComponent.PUSHED_BUTTON_CLASS);
|
||||||
|
|
||||||
|
if (currentlyDown) {
|
||||||
|
button.removeClass(EscDshotDirectionComponent.PUSHED_BUTTON_CLASS);
|
||||||
|
this._motorDriver.setEscSpinDirection(motorIndex, DshotCommand.dshotCommands_e.DSHOT_CMD_SPIN_DIRECTION_1);
|
||||||
|
} else {
|
||||||
|
this._motorDriver.setEscSpinDirection(motorIndex, DshotCommand.dshotCommands_e.DSHOT_CMD_SPIN_DIRECTION_2);
|
||||||
|
button.addClass(EscDshotDirectionComponent.PUSHED_BUTTON_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._activateWizardMotorButtons(this._buttonTimeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
_changeSelectedMotor(newIndex)
|
||||||
|
{
|
||||||
|
if (this._selectedMotor >= 0) {
|
||||||
|
this._motorButtons[this._selectedMotor].addClass(EscDshotDirectionComponent.PUSHED_BUTTON_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._selectedMotor = newIndex;
|
||||||
|
|
||||||
|
if (this._selectedMotor > -1) {
|
||||||
|
this._motorButtons[this._selectedMotor].removeClass(EscDshotDirectionComponent.PUSHED_BUTTON_CLASS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close()
|
||||||
|
{
|
||||||
|
this._motorDriver.stopAllMotorsNow();
|
||||||
|
this._motorDriver.deactivate();
|
||||||
|
this._resetGui();
|
||||||
|
}
|
||||||
|
|
||||||
|
_resetGui()
|
||||||
|
{
|
||||||
|
this._toggleMainContent(false);
|
||||||
|
this._domStartNormalBlock.hide();
|
||||||
|
this._domStartWizardBlock.hide();
|
||||||
|
|
||||||
|
this._domAgreeSafetyCheckBox.prop('checked', false);
|
||||||
|
this._domAgreeSafetyCheckBox.trigger('change');
|
||||||
|
this._domSecondActionDiv.toggle(false);
|
||||||
|
this._changeSelectedMotor(-1);
|
||||||
|
|
||||||
|
this._checkForConfigurationErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkForConfigurationErrors()
|
||||||
|
{
|
||||||
|
let anyError = false;
|
||||||
|
|
||||||
|
this._domWrongProtocolMessage.hide();
|
||||||
|
this._domWrongMixerMessage.hide();
|
||||||
|
this._domWrongFirmwareMessage.hide();
|
||||||
|
|
||||||
|
if (!this._escProtocolIsDshot) {
|
||||||
|
anyError = true;
|
||||||
|
this._domWrongProtocolMessage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._numberOfMotors <= 0) {
|
||||||
|
anyError = true;
|
||||||
|
this._domWrongMixerMessage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
|
||||||
|
// if BF4.2 or older - show the error message
|
||||||
|
anyError = true;
|
||||||
|
this._domWrongFirmwareMessage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anyError) {
|
||||||
|
this._domMainContentBlock.hide();
|
||||||
|
this._domWarningContentBlock.hide();
|
||||||
|
this._domStartNormalBlock.hide();
|
||||||
|
this._domStartWizardBlock.hide();
|
||||||
|
this._domConfigErrors.show();
|
||||||
|
} else {
|
||||||
|
this._domConfigErrors.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_onStartButtonClicked()
|
||||||
|
{
|
||||||
|
this._toggleMainContent(true);
|
||||||
|
this._domWizardBlock.toggle(false);
|
||||||
|
this._domNormalDialogBlock.toggle(true);
|
||||||
|
this._motorDriver.activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
_onStartWizardButtonClicked()
|
||||||
|
{
|
||||||
|
this._domSpinningWizard.toggle(false);
|
||||||
|
this._domSpinWizardButton.toggle(true);
|
||||||
|
this._toggleMainContent(true);
|
||||||
|
this._domWizardBlock.toggle(true);
|
||||||
|
this._domNormalDialogBlock.toggle(false);
|
||||||
|
this._motorDriver.activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSpinWizardButtonClicked()
|
||||||
|
{
|
||||||
|
for (let i = 0; i < this._numberOfMotors; i++) {
|
||||||
|
this._wizardMotorButtons[i].removeClass(EscDshotDirectionComponent.PUSHED_BUTTON_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._motorDriver.setEscSpinDirection(DshotCommand.ALL_MOTORS, DshotCommand.dshotCommands_e.DSHOT_CMD_SPIN_DIRECTION_1);
|
||||||
|
|
||||||
|
this._domSpinWizardButton.toggle(false);
|
||||||
|
this._domSpinningWizard.toggle(true);
|
||||||
|
this._motorDriver.spinAllMotors();
|
||||||
|
|
||||||
|
this._activateWizardMotorButtons(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onStopWizardButtonClicked()
|
||||||
|
{
|
||||||
|
this._domSpinWizardButton.toggle(true);
|
||||||
|
this._domSpinningWizard.toggle(false);
|
||||||
|
this._motorDriver.stopAllMotorsNow();
|
||||||
|
this._deactivateWizardMotorButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
_toggleMainContent(value)
|
||||||
|
{
|
||||||
|
this._domWarningContentBlock.toggle(!value);
|
||||||
|
this._domMainContentBlock.toggle(value);
|
||||||
|
this._domConfigErrors.toggle(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
155
src/components/EscDshotDirection/EscDshotDirectionMotorDriver.js
Normal file
155
src/components/EscDshotDirection/EscDshotDirectionMotorDriver.js
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class EscDshotDirectionMotorDriver
|
||||||
|
{
|
||||||
|
constructor(motorConfig, motorDriverQueueIntervalMs, motorDriverStopMotorsPauseMs)
|
||||||
|
{
|
||||||
|
this._numberOfMotors = motorConfig.numberOfMotors;
|
||||||
|
this._motorStopValue = motorConfig.motorStopValue;
|
||||||
|
this._motorSpinValue = motorConfig.motorSpinValue;
|
||||||
|
this._motorDriverStopMotorsPauseMs = motorDriverStopMotorsPauseMs;
|
||||||
|
|
||||||
|
this._state = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < this._numberOfMotors; i++)
|
||||||
|
{
|
||||||
|
this._state.push(this._motorStopValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._stateStack = [];
|
||||||
|
|
||||||
|
this._EscDshotCommandQueue = new EscDshotCommandQueue(motorDriverQueueIntervalMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
activate()
|
||||||
|
{
|
||||||
|
this._EscDshotCommandQueue.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
deactivate()
|
||||||
|
{
|
||||||
|
this._EscDshotCommandQueue.stopWhenEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
stopMotor(motorIndex)
|
||||||
|
{
|
||||||
|
this._spinMotor(motorIndex, this._motorStopValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
spinMotor(motorIndex)
|
||||||
|
{
|
||||||
|
this._spinMotor(motorIndex, this._motorSpinValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
spinAllMotors()
|
||||||
|
{
|
||||||
|
this._spinAllMotors(this._motorSpinValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
stopAllMotors()
|
||||||
|
{
|
||||||
|
this._spinAllMotors(this._motorStopValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
stopAllMotorsNow()
|
||||||
|
{
|
||||||
|
this._EscDshotCommandQueue.clear();
|
||||||
|
this._spinAllMotors(this._motorStopValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
setEscSpinDirection(motorIndex, direction)
|
||||||
|
{
|
||||||
|
let needStopMotor = false;
|
||||||
|
|
||||||
|
if (DshotCommand.ALL_MOTORS === motorIndex) {
|
||||||
|
needStopMotor = this._isAnythingSpinning();
|
||||||
|
} else {
|
||||||
|
needStopMotor = this._isMotorSpinning(motorIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needStopMotor) {
|
||||||
|
this._pushState();
|
||||||
|
this._spinMotor(motorIndex, this._motorStopValue);
|
||||||
|
this._EscDshotCommandQueue.pushPause(this._motorDriverStopMotorsPauseMs);
|
||||||
|
this._sendEscSpinDirection(motorIndex, direction);
|
||||||
|
this._popState();
|
||||||
|
this._sendState();
|
||||||
|
} else {
|
||||||
|
this._sendEscSpinDirection(motorIndex, direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_pushState()
|
||||||
|
{
|
||||||
|
const state = [...this._state];
|
||||||
|
this._stateStack.push(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
_popState()
|
||||||
|
{
|
||||||
|
const state = this._stateStack.pop();
|
||||||
|
this._state = [...state];
|
||||||
|
}
|
||||||
|
|
||||||
|
_isAnythingSpinning()
|
||||||
|
{
|
||||||
|
let result = false;
|
||||||
|
|
||||||
|
for (let i = 0; i < this._numberOfMotors; i++) {
|
||||||
|
if (this._motorStopValue !== this._state[i]) {
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isMotorSpinning(motorIndex)
|
||||||
|
{
|
||||||
|
return (this._motorStopValue !== this._state[motorIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendEscSpinDirection(motorIndex, direction)
|
||||||
|
{
|
||||||
|
const buffer = [];
|
||||||
|
buffer.push8(DshotCommand.dshotCommandType_e.DSHOT_CMD_TYPE_BLOCKING);
|
||||||
|
buffer.push8(motorIndex);
|
||||||
|
buffer.push8(2); // two commands
|
||||||
|
buffer.push8(direction);
|
||||||
|
buffer.push8(DshotCommand.dshotCommands_e.DSHOT_CMD_SAVE_SETTINGS);
|
||||||
|
this._EscDshotCommandQueue.pushCommand(MSPCodes.MSP2_SEND_DSHOT_COMMAND, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
_spinMotor(motorIndex, value)
|
||||||
|
{
|
||||||
|
if (DshotCommand.ALL_MOTORS === motorIndex) {
|
||||||
|
this._spinAllMotors(value);
|
||||||
|
} else {
|
||||||
|
this._state[motorIndex] = value;
|
||||||
|
this._sendState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_spinAllMotors(value)
|
||||||
|
{
|
||||||
|
for (let i = 0; i < this._numberOfMotors; i++) {
|
||||||
|
this._state[i] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._sendState();
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendState()
|
||||||
|
{
|
||||||
|
const buffer = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < this._numberOfMotors; i++) {
|
||||||
|
buffer.push16(this._state[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._EscDshotCommandQueue.pushCommand(MSPCodes.MSP_SET_MOTOR, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
177
src/components/EscDshotDirection/Styles.css
Normal file
177
src/components/EscDshotDirection/Styles.css
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
.escDshotDirection-Component {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
flex-flow: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirection-ComponentHeader {
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-MainContent {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
flex-flow: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-Warning {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
flex-flow: column;
|
||||||
|
border-top: 1px solid var(--superSubtleAccent);
|
||||||
|
padding-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirectionToggleParentContainer {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirectionToggleNarrow {
|
||||||
|
margin-right: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirectionDialog-ToggleWide {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirectionDialog-RiskNoticeText {
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirectionDialogInformationNotice {
|
||||||
|
font-size: 1.0em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-MixerPreview {
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 9px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-MixerPreviewImg {
|
||||||
|
display: block;
|
||||||
|
width: 160px;
|
||||||
|
height: 160px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-MainContent h4 {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-MainContent .red-text {
|
||||||
|
color: #EE0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-ActionHint, #escDshotDirectionDialog-SecondHint, #escDshotDirectionDialog-WizardActionHint {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-ActionHintSafety, #escDshotDirectionDialog-SecondHintSafety {
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-SelectMotorButtonsWrapper, #escDshotDirectionDialog-WizardMotorButtons {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-SelectMotorButtonsWrapper .regular-button, #escDshotDirectionDialog-WizardMotorButtons .regular-button {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 34px;
|
||||||
|
padding: 0px;
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
border-radius: 17px;
|
||||||
|
width: 34px;
|
||||||
|
height: 34px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-NormalDialog .regular-button.pushed:hover {
|
||||||
|
background-color: #993333;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-NormalDialog .regular-button:hover {
|
||||||
|
background-color: #993333;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-MainContent .regular-button.highlighted {
|
||||||
|
background-color: #EE2222;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-CommandsWrapper {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-CommandSpin {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 224px;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-CommandsWrapper .regular-button {
|
||||||
|
width: 130px;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.escDshotDirectionErrorTextBlock {
|
||||||
|
margin-top: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-contents {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
#escDshotDirectionDialog-SpinWizard, #escDshotDirectionDialog-StopWizard {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 160px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirectionDialog-InformationNotice {
|
||||||
|
margin-top: 18px;
|
||||||
|
padding-top: 16px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
border-top: 1px solid var(--superSubtleAccent);
|
||||||
|
border-bottom: 1px solid var(--superSubtleAccent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirectionDialog-StartButton {
|
||||||
|
width: 80px;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 0px;
|
||||||
|
margin-right: 16px;
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirectionDialog-Buttons {
|
||||||
|
float: left;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.escDshotDirectionDialog-StartBlock {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ class MotorOutputReorderComponent
|
||||||
_readDom()
|
_readDom()
|
||||||
{
|
{
|
||||||
this._domAgreeSafetyCheckBox = $('#motorsEnableTestMode-dialogMotorOutputReorder');
|
this._domAgreeSafetyCheckBox = $('#motorsEnableTestMode-dialogMotorOutputReorder');
|
||||||
this._domAgreeButton = $('#dialogMotorOutputReorderAgreeButton');
|
this._domStartButton = $('#dialogMotorOutputReorderAgreeButton');
|
||||||
this._domStartOverButton = $('#motorsRemapDialogStartOver');
|
this._domStartOverButton = $('#motorsRemapDialogStartOver');
|
||||||
this._domSaveButton = $('#motorsRemapDialogSave');
|
this._domSaveButton = $('#motorsRemapDialogSave');
|
||||||
this._domMainContentBlock = $('#dialogMotorOutputReorderMainContent');
|
this._domMainContentBlock = $('#dialogMotorOutputReorderMainContent');
|
||||||
|
@ -44,12 +44,12 @@ class MotorOutputReorderComponent
|
||||||
this._domAgreeSafetyCheckBox.change(() =>
|
this._domAgreeSafetyCheckBox.change(() =>
|
||||||
{
|
{
|
||||||
const enabled = this._domAgreeSafetyCheckBox.is(':checked');
|
const enabled = this._domAgreeSafetyCheckBox.is(':checked');
|
||||||
this._domAgreeButton.toggle(enabled);
|
this._domStartButton.toggle(enabled);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._domAgreeButton.click(() =>
|
this._domStartButton.click(() =>
|
||||||
{
|
{
|
||||||
this._onAgreeButtonClicked();
|
this._onStartButtonClicked();
|
||||||
});
|
});
|
||||||
this._domStartOverButton.click(() =>
|
this._domStartOverButton.click(() =>
|
||||||
{
|
{
|
||||||
|
@ -75,7 +75,7 @@ class MotorOutputReorderComponent
|
||||||
{
|
{
|
||||||
this._domMainContentBlock.hide();
|
this._domMainContentBlock.hide();
|
||||||
this._domWarningContentBlock.show();
|
this._domWarningContentBlock.show();
|
||||||
this._domAgreeButton.hide();
|
this._domStartButton.hide();
|
||||||
|
|
||||||
this._domAgreeSafetyCheckBox.prop('checked', false);
|
this._domAgreeSafetyCheckBox.prop('checked', false);
|
||||||
this._domAgreeSafetyCheckBox.change();
|
this._domAgreeSafetyCheckBox.change();
|
||||||
|
@ -138,7 +138,7 @@ class MotorOutputReorderComponent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onAgreeButtonClicked()
|
_onStartButtonClicked()
|
||||||
{
|
{
|
||||||
this._domActionHintBlock.text(i18n.getMessage("motorOutputReorderDialogSelectSpinningMotor"));
|
this._domActionHintBlock.text(i18n.getMessage("motorOutputReorderDialogSelectSpinningMotor"));
|
||||||
this._domWarningContentBlock.hide();
|
this._domWarningContentBlock.hide();
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.motorOutputReorderComponentHeader {
|
.motorOutputReorderComponentHeader {
|
||||||
border-bottom: 1px solid var(--accent);
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
--gimbalBackground: var(--subtleAccent);
|
--gimbalBackground: var(--subtleAccent);
|
||||||
--gimbalCrosshair: var(--mutedText);
|
--gimbalCrosshair: var(--mutedText);
|
||||||
--switcherysecond: #858585;
|
--switcherysecond: #858585;
|
||||||
|
--pushedButton-background: #616161;
|
||||||
|
--pushedButton-fontColor: #ffffff;
|
||||||
|
--hoverButton-background: #ffcc3e;
|
||||||
|
--superSubtleAccent: #595959;
|
||||||
}
|
}
|
||||||
|
|
||||||
.background_paper {
|
.background_paper {
|
||||||
|
@ -24,6 +28,11 @@ body {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::backdrop {
|
||||||
|
background-image: none;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
#options-window {
|
#options-window {
|
||||||
background-color: #393b3a;
|
background-color: #393b3a;
|
||||||
}
|
}
|
||||||
|
@ -219,7 +228,7 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-auxiliary .buttons a:hover {
|
.tab-auxiliary .buttons a:hover {
|
||||||
background-color: #393b3a;
|
background-color: var(--hoverButton-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -357,7 +366,7 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-gps #loadmap .controls a:hover {
|
.tab-gps #loadmap .controls a:hover {
|
||||||
background-color: #393b3a;
|
background-color: var(--hoverButton-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-gps #loadmap .controls a:active {
|
.tab-gps #loadmap .controls a:active {
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
--gimbalBackground: #eee;
|
--gimbalBackground: #eee;
|
||||||
--gimbalCrosshair: var(--subtleAccent);
|
--gimbalCrosshair: var(--subtleAccent);
|
||||||
--switcherysecond: #c4c4c4;
|
--switcherysecond: #c4c4c4;
|
||||||
|
--pushedButton-background: #c4c4c4;
|
||||||
|
--pushedButton-fontColor: #000000;
|
||||||
|
--hoverButton-background: #ffcc3e;
|
||||||
|
--superSubtleAccent: #CCCCCC;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
@ -40,6 +44,11 @@ body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::backdrop {
|
||||||
|
background-image: none;
|
||||||
|
background-color: rgba(1, 1, 1, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: var(--linkText);
|
color: var(--linkText);
|
||||||
|
@ -140,7 +149,11 @@ input[type="number"]::-webkit-inner-spin-button {
|
||||||
font-weight: bold !important;
|
font-weight: bold !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-negative-italic {
|
||||||
|
color: var(--error) !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
/** Main wrapper **/
|
/** Main wrapper **/
|
||||||
#main-wrapper {
|
#main-wrapper {
|
||||||
|
@ -1478,7 +1491,7 @@ dialog .dialog_toolbar .btn a {
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog .dialog_toolbar .btn a:hover {
|
dialog .dialog_toolbar .btn a:hover {
|
||||||
background-color: #ffcc3e;
|
background-color: var(--hoverButton-background);
|
||||||
transition: all ease 0.2s;
|
transition: all ease 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1574,7 +1587,7 @@ dialog .dialog_toolbar .btn a.disabled {
|
||||||
}
|
}
|
||||||
|
|
||||||
.content_toolbar .btn a:hover {
|
.content_toolbar .btn a:hover {
|
||||||
background-color: #ffcc3e;
|
background-color: var(--hoverButton-background);
|
||||||
transition: all ease 0.2s;
|
transition: all ease 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1862,7 +1875,7 @@ dialog .dialog_toolbar .btn a.disabled {
|
||||||
}
|
}
|
||||||
|
|
||||||
.fixed_band .save_btn a:hover {
|
.fixed_band .save_btn a:hover {
|
||||||
background-color: #ffcc3f;
|
background-color: var(--hoverButton-background);
|
||||||
transition: all ease 0.2s;
|
transition: all ease 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1898,7 +1911,7 @@ dialog .dialog_toolbar .btn a.disabled {
|
||||||
}
|
}
|
||||||
|
|
||||||
.default_btn a:hover {
|
.default_btn a:hover {
|
||||||
background-color: #ffcc3f;
|
background-color: var(--hoverButton-background);
|
||||||
color: #000;
|
color: #000;
|
||||||
text-shadow: 0 1px rgba(255, 255, 255, 0.25);
|
text-shadow: 0 1px rgba(255, 255, 255, 0.25);
|
||||||
transition: all ease 0.2s;
|
transition: all ease 0.2s;
|
||||||
|
@ -1907,7 +1920,7 @@ dialog .dialog_toolbar .btn a.disabled {
|
||||||
}
|
}
|
||||||
|
|
||||||
.default_btn a:active {
|
.default_btn a:active {
|
||||||
background-color: #ffcc3f;
|
background-color: var(--hoverButton-background);
|
||||||
transition: all ease 0.0s;
|
transition: all ease 0.0s;
|
||||||
box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.35);
|
box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.35);
|
||||||
}
|
}
|
||||||
|
@ -1917,6 +1930,7 @@ dialog .dialog_toolbar .btn a.disabled {
|
||||||
}
|
}
|
||||||
|
|
||||||
.regular-button {
|
.regular-button {
|
||||||
|
-webkit-user-drag: none;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
@ -1934,6 +1948,16 @@ dialog .dialog_toolbar .btn a.disabled {
|
||||||
line-height: 28px;
|
line-height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.regular-button:hover {
|
||||||
|
background-color: var(--hoverButton-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.regular-button.pushed {
|
||||||
|
background-color: var(--pushedButton-background);
|
||||||
|
color: var(--pushedButton-fontColor);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
.small {
|
.small {
|
||||||
width: auto;
|
width: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
.tab-motors #dialogMotorOutputReorder {
|
.tab-motors #dialogMotorOutputReorder {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height:440px
|
height: 440px
|
||||||
;}
|
;}
|
||||||
|
|
||||||
.tab-motors #dialogMotorOutputReorderContentWrapper {
|
.tab-motors #dialogMotorOutputReorderContentWrapper {
|
||||||
|
@ -39,6 +39,31 @@
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-motors #escDshotDirectionDialog-closebtn {
|
||||||
|
margin-right: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
position: absolute;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-motors #escDshotDirectionDialog {
|
||||||
|
width: 400px;
|
||||||
|
height: 440px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-motors #escDshotDirectionDialog-ContentWrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-motors #escDshotDirectionDialog-Content {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-motors .mixerPreview img {
|
.tab-motors .mixerPreview img {
|
||||||
width: 120px;
|
width: 120px;
|
||||||
height: 120px;
|
height: 120px;
|
||||||
|
@ -457,4 +482,16 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-motors #escDshotDirectionDialog- {
|
||||||
|
position: fixed;
|
||||||
|
width: calc(100% - 2em);
|
||||||
|
bottom: 0;
|
||||||
|
top: 56px;
|
||||||
|
border-radius: unset;
|
||||||
|
border: none;
|
||||||
|
overflow: auto;
|
||||||
|
margin: 0;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,4 +181,5 @@ const MSPCodes = {
|
||||||
MSP2_BETAFLIGHT_BIND: 0x3000,
|
MSP2_BETAFLIGHT_BIND: 0x3000,
|
||||||
MSP2_MOTOR_OUTPUT_REORDERING: 0x3001,
|
MSP2_MOTOR_OUTPUT_REORDERING: 0x3001,
|
||||||
MSP2_SET_MOTOR_OUTPUT_REORDERING: 0x3002,
|
MSP2_SET_MOTOR_OUTPUT_REORDERING: 0x3002,
|
||||||
|
MSP2_SEND_DSHOT_COMMAND: 0x3003,
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,26 +57,6 @@ function MspHelper() {
|
||||||
self.mspMultipleCache = [];
|
self.mspMultipleCache = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
MspHelper.prototype.reorderPwmProtocols = function (protocol) {
|
|
||||||
let result = protocol;
|
|
||||||
if (semver.lt(FC.CONFIG.apiVersion, "1.26.0")) {
|
|
||||||
switch (protocol) {
|
|
||||||
case 5:
|
|
||||||
result = 7;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
result = 5;
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
MspHelper.prototype.process_data = function(dataHandler) {
|
MspHelper.prototype.process_data = function(dataHandler) {
|
||||||
const self = this;
|
const self = this;
|
||||||
const data = dataHandler.dataView; // DataView (allowing us to view arrayBuffer as struct/union)
|
const data = dataHandler.dataView; // DataView (allowing us to view arrayBuffer as struct/union)
|
||||||
|
@ -1039,7 +1019,7 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
||||||
FC.PID_ADVANCED_CONFIG.gyro_sync_denom = data.readU8();
|
FC.PID_ADVANCED_CONFIG.gyro_sync_denom = data.readU8();
|
||||||
FC.PID_ADVANCED_CONFIG.pid_process_denom = data.readU8();
|
FC.PID_ADVANCED_CONFIG.pid_process_denom = data.readU8();
|
||||||
FC.PID_ADVANCED_CONFIG.use_unsyncedPwm = data.readU8();
|
FC.PID_ADVANCED_CONFIG.use_unsyncedPwm = data.readU8();
|
||||||
FC.PID_ADVANCED_CONFIG.fast_pwm_protocol = self.reorderPwmProtocols(data.readU8());
|
FC.PID_ADVANCED_CONFIG.fast_pwm_protocol = EscProtocols.ReorderPwmProtocols(FC.CONFIG.apiVersion, data.readU8());
|
||||||
FC.PID_ADVANCED_CONFIG.motor_pwm_rate = data.readU16();
|
FC.PID_ADVANCED_CONFIG.motor_pwm_rate = data.readU16();
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, "1.24.0")) {
|
if (semver.gte(FC.CONFIG.apiVersion, "1.24.0")) {
|
||||||
FC.PID_ADVANCED_CONFIG.digitalIdlePercent = data.readU16() / 100;
|
FC.PID_ADVANCED_CONFIG.digitalIdlePercent = data.readU16() / 100;
|
||||||
|
@ -1569,6 +1549,9 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
||||||
case MSPCodes.MSP2_SET_MOTOR_OUTPUT_REORDERING:
|
case MSPCodes.MSP2_SET_MOTOR_OUTPUT_REORDERING:
|
||||||
console.log('Motor output reordering set');
|
console.log('Motor output reordering set');
|
||||||
break;
|
break;
|
||||||
|
case MSPCodes.MSP2_SEND_DSHOT_COMMAND:
|
||||||
|
console.log('DSHOT command sent');
|
||||||
|
break;
|
||||||
|
|
||||||
case MSPCodes.MSP_MULTIPLE_MSP:
|
case MSPCodes.MSP_MULTIPLE_MSP:
|
||||||
|
|
||||||
|
@ -1981,7 +1964,7 @@ MspHelper.prototype.crunch = function(code) {
|
||||||
buffer.push8(FC.PID_ADVANCED_CONFIG.gyro_sync_denom)
|
buffer.push8(FC.PID_ADVANCED_CONFIG.gyro_sync_denom)
|
||||||
.push8(FC.PID_ADVANCED_CONFIG.pid_process_denom)
|
.push8(FC.PID_ADVANCED_CONFIG.pid_process_denom)
|
||||||
.push8(FC.PID_ADVANCED_CONFIG.use_unsyncedPwm)
|
.push8(FC.PID_ADVANCED_CONFIG.use_unsyncedPwm)
|
||||||
.push8(self.reorderPwmProtocols(FC.PID_ADVANCED_CONFIG.fast_pwm_protocol))
|
.push8(EscProtocols.ReorderPwmProtocols(FC.CONFIG.apiVersion, FC.PID_ADVANCED_CONFIG.fast_pwm_protocol))
|
||||||
.push16(FC.PID_ADVANCED_CONFIG.motor_pwm_rate);
|
.push16(FC.PID_ADVANCED_CONFIG.motor_pwm_rate);
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, "1.24.0")) {
|
if (semver.gte(FC.CONFIG.apiVersion, "1.24.0")) {
|
||||||
buffer.push16(FC.PID_ADVANCED_CONFIG.digitalIdlePercent * 100);
|
buffer.push16(FC.PID_ADVANCED_CONFIG.digitalIdlePercent * 100);
|
||||||
|
@ -2278,6 +2261,10 @@ MspHelper.prototype.crunch = function(code) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSPCodes.MSP2_SEND_DSHOT_COMMAND:
|
||||||
|
buffer.push8(1);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,14 +213,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshMixerPreview() {
|
function refreshMixerPreview() {
|
||||||
const mixer = FC.MIXER_CONFIG.mixer
|
const imgSrc = CommonUtils.GetMixerImageSrc(FC.MIXER_CONFIG.mixer, FC.MIXER_CONFIG.reverseMotorDir, FC.CONFIG.apiVersion);
|
||||||
let reverse = "";
|
$('.mixerPreview img').attr('src', imgSrc);
|
||||||
|
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
|
|
||||||
reverse = FC.MIXER_CONFIG.reverseMotorDir ? "_reversed" : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.mixerPreview img').attr('src', './resources/motor_order/' + mixerList[mixer - 1].image + reverse + '.svg');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const reverseMotorSwitch_e = $('#reverseMotorSwitch');
|
const reverseMotorSwitch_e = $('#reverseMotorSwitch');
|
||||||
|
@ -462,34 +456,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ESC protocols
|
// ESC protocols
|
||||||
const escProtocols = [
|
const escProtocols = EscProtocols.GetAvailableProtocols(FC.CONFIG.apiVersion);
|
||||||
'PWM',
|
|
||||||
'ONESHOT125',
|
|
||||||
'ONESHOT42',
|
|
||||||
'MULTISHOT',
|
|
||||||
];
|
|
||||||
|
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, "1.20.0")) {
|
|
||||||
escProtocols.push('BRUSHED');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_31)) {
|
|
||||||
escProtocols.push('DSHOT150');
|
|
||||||
escProtocols.push('DSHOT300');
|
|
||||||
escProtocols.push('DSHOT600');
|
|
||||||
|
|
||||||
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_42)) {
|
|
||||||
escProtocols.push('DSHOT1200');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
|
|
||||||
escProtocols.push('PROSHOT1000');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43)) {
|
|
||||||
escProtocols.push('DISABLED');
|
|
||||||
}
|
|
||||||
|
|
||||||
const esc_protocol_e = $('select.escprotocol');
|
const esc_protocol_e = $('select.escprotocol');
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@ TABS.motors = {
|
||||||
// These are translated into proper Dshot values on the flight controller
|
// These are translated into proper Dshot values on the flight controller
|
||||||
DSHOT_DISARMED_VALUE: 1000,
|
DSHOT_DISARMED_VALUE: 1000,
|
||||||
DSHOT_MAX_VALUE: 2000,
|
DSHOT_MAX_VALUE: 2000,
|
||||||
DSHOT_3D_NEUTRAL: 1500
|
DSHOT_3D_NEUTRAL: 1500,
|
||||||
|
numberOfValidOutputs: -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
TABS.motors.initialize = function (callback) {
|
TABS.motors.initialize = function (callback) {
|
||||||
|
@ -105,7 +106,7 @@ TABS.motors.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function initDataArray(length) {
|
function initDataArray(length) {
|
||||||
const data = new Array(length);
|
const data = Array.from({length: length});
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
data[i] = [];
|
data[i] = [];
|
||||||
data[i].min = -1;
|
data[i].min = -1;
|
||||||
|
@ -126,8 +127,8 @@ TABS.motors.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (data[0].length > 300) {
|
while (data[0].length > 300) {
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (const item of data) {
|
||||||
data[i].shift();
|
item.shift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sampleNumber + 1;
|
return sampleNumber + 1;
|
||||||
|
@ -220,13 +221,8 @@ TABS.motors.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_model(mixer) {
|
function update_model(mixer) {
|
||||||
let reverse = "";
|
const imgSrc = CommonUtils.GetMixerImageSrc(mixer, FC.MIXER_CONFIG.reverseMotorDir, FC.CONFIG.apiVersion);
|
||||||
|
$('.mixerPreview img').attr('src', imgSrc);
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
|
|
||||||
reverse = FC.MIXER_CONFIG.reverseMotorDir ? "_reversed" : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.mixerPreview img').attr('src', './resources/motor_order/' + mixerList[mixer - 1].image + reverse + '.svg');
|
|
||||||
|
|
||||||
const motorOutputReorderConfig = new MotorOutputReorderConfig(100);
|
const motorOutputReorderConfig = new MotorOutputReorderConfig(100);
|
||||||
const domMotorOutputReorderDialogOpen = $('#motorOutputReorderDialogOpen');
|
const domMotorOutputReorderDialogOpen = $('#motorOutputReorderDialogOpen');
|
||||||
|
@ -234,6 +230,8 @@ TABS.motors.initialize = function (callback) {
|
||||||
const isMotorReorderingAvailable = (mixerList[mixer - 1].name in motorOutputReorderConfig)
|
const isMotorReorderingAvailable = (mixerList[mixer - 1].name in motorOutputReorderConfig)
|
||||||
&& (FC.MOTOR_OUTPUT_ORDER) && (FC.MOTOR_OUTPUT_ORDER.length > 0);
|
&& (FC.MOTOR_OUTPUT_ORDER) && (FC.MOTOR_OUTPUT_ORDER.length > 0);
|
||||||
domMotorOutputReorderDialogOpen.toggle(isMotorReorderingAvailable);
|
domMotorOutputReorderDialogOpen.toggle(isMotorReorderingAvailable);
|
||||||
|
|
||||||
|
self.escProtocolIsDshot = EscProtocols.IsProtocolDshot(FC.CONFIG.apiVersion, FC.PID_ADVANCED_CONFIG.fast_pwm_protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
function process_html() {
|
function process_html() {
|
||||||
|
@ -244,12 +242,6 @@ TABS.motors.initialize = function (callback) {
|
||||||
|
|
||||||
self.feature3DEnabled = FC.FEATURE_CONFIG.features.isEnabled('3D');
|
self.feature3DEnabled = FC.FEATURE_CONFIG.features.isEnabled('3D');
|
||||||
|
|
||||||
if (FC.PID_ADVANCED_CONFIG.fast_pwm_protocol >= TABS.configuration.DSHOT_PROTOCOL_MIN_VALUE) {
|
|
||||||
self.escProtocolIsDshot = true;
|
|
||||||
} else {
|
|
||||||
self.escProtocolIsDshot = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#motorsEnableTestMode').prop('checked', false);
|
$('#motorsEnableTestMode').prop('checked', false);
|
||||||
|
|
||||||
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_42) || !(FC.MOTOR_CONFIG.use_dshot_telemetry || FC.MOTOR_CONFIG.use_esc_sensor)) {
|
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_42) || !(FC.MOTOR_CONFIG.use_dshot_telemetry || FC.MOTOR_CONFIG.use_esc_sensor)) {
|
||||||
|
@ -416,7 +408,7 @@ TABS.motors.initialize = function (callback) {
|
||||||
function computeAndUpdate(sensor_data, data, max_read) {
|
function computeAndUpdate(sensor_data, data, max_read) {
|
||||||
let sum = 0.0;
|
let sum = 0.0;
|
||||||
for (let j = 0, jlength = data.length; j < jlength; j++) {
|
for (let j = 0, jlength = data.length; j < jlength; j++) {
|
||||||
for (let k = 0, klength = data[j].length; k < klength; k++){
|
for (let k = 0, klength = data[j].length; k < klength; k++) {
|
||||||
sum += data[j][k][1]*data[j][k][1];
|
sum += data[j][k][1]*data[j][k][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,6 +447,7 @@ TABS.motors.initialize = function (callback) {
|
||||||
motor_mah_drawing_e.text(i18n.getMessage('motorsADrawingValue', [FC.ANALOG.amperage.toFixed(2)]));
|
motor_mah_drawing_e.text(i18n.getMessage('motorsADrawingValue', [FC.ANALOG.amperage.toFixed(2)]));
|
||||||
motor_mah_drawn_e.text(i18n.getMessage('motorsmAhDrawnValue', [FC.ANALOG.mAhdrawn]));
|
motor_mah_drawn_e.text(i18n.getMessage('motorsmAhDrawnValue', [FC.ANALOG.mAhdrawn]));
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.interval_add('motors_power_data_pull_slow', power_data_pull, 250, true); // 4 fps
|
GUI.interval_add('motors_power_data_pull_slow', power_data_pull, 250, true); // 4 fps
|
||||||
|
|
||||||
$('a.reset_max').click(function () {
|
$('a.reset_max').click(function () {
|
||||||
|
@ -463,7 +456,7 @@ TABS.motors.initialize = function (callback) {
|
||||||
accelOffsetEstablished = false;
|
accelOffsetEstablished = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
const numberOfValidOutputs = (FC.MOTOR_DATA.indexOf(0) > -1) ? FC.MOTOR_DATA.indexOf(0) : 8;
|
self.numberOfValidOutputs = (FC.MOTOR_DATA.indexOf(0) > -1) ? FC.MOTOR_DATA.indexOf(0) : 8;
|
||||||
let rangeMin;
|
let rangeMin;
|
||||||
let rangeMax;
|
let rangeMax;
|
||||||
let neutral3d;
|
let neutral3d;
|
||||||
|
@ -526,7 +519,7 @@ TABS.motors.initialize = function (callback) {
|
||||||
|
|
||||||
function setSlidersEnabled(isEnabled) {
|
function setSlidersEnabled(isEnabled) {
|
||||||
if (isEnabled && !self.armed) {
|
if (isEnabled && !self.armed) {
|
||||||
$('div.sliders input').slice(0, numberOfValidOutputs).prop('disabled', false);
|
$('div.sliders input').slice(0, self.numberOfValidOutputs).prop('disabled', false);
|
||||||
|
|
||||||
// unlock master slider
|
// unlock master slider
|
||||||
$('div.sliders input:last').prop('disabled', false);
|
$('div.sliders input:last').prop('disabled', false);
|
||||||
|
@ -583,14 +576,14 @@ TABS.motors.initialize = function (callback) {
|
||||||
const val = $(this).val();
|
const val = $(this).val();
|
||||||
|
|
||||||
$('div.sliders input:not(:disabled, :last)').val(val);
|
$('div.sliders input:not(:disabled, :last)').val(val);
|
||||||
$('div.values li:not(:last)').slice(0, numberOfValidOutputs).text(val);
|
$('div.values li:not(:last)').slice(0, self.numberOfValidOutputs).text(val);
|
||||||
$('div.sliders input:not(:last):first').trigger('input');
|
$('div.sliders input:not(:last):first').trigger('input');
|
||||||
});
|
});
|
||||||
|
|
||||||
// check if motors are already spinning
|
// check if motors are already spinning
|
||||||
let motorsRunning = false;
|
let motorsRunning = false;
|
||||||
|
|
||||||
for (let i = 0; i < numberOfValidOutputs; i++) {
|
for (let i = 0; i < self.numberOfValidOutputs; i++) {
|
||||||
if (!self.feature3DEnabled) {
|
if (!self.feature3DEnabled) {
|
||||||
if (FC.MOTOR_DATA[i] > rangeMin) {
|
if (FC.MOTOR_DATA[i] > rangeMin) {
|
||||||
motorsRunning = true;
|
motorsRunning = true;
|
||||||
|
@ -747,7 +740,11 @@ TABS.motors.initialize = function (callback) {
|
||||||
zeroThrottleValue = neutral3d;
|
zeroThrottleValue = neutral3d;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_motor_output_reordering_dialog(content_ready, zeroThrottleValue);
|
setup_motor_output_reordering_dialog(SetupEscDshotDirectionDialogCallback, zeroThrottleValue);
|
||||||
|
|
||||||
|
function SetupEscDshotDirectionDialogCallback() {
|
||||||
|
SetupdescDshotDirectionDialog(content_ready, zeroThrottleValue);
|
||||||
|
}
|
||||||
|
|
||||||
function content_ready() {
|
function content_ready() {
|
||||||
GUI.content_ready(callback);
|
GUI.content_ready(callback);
|
||||||
|
@ -764,9 +761,9 @@ TABS.motors.initialize = function (callback) {
|
||||||
callbackFunction, mixerList[FC.MIXER_CONFIG.mixer - 1].name,
|
callbackFunction, mixerList[FC.MIXER_CONFIG.mixer - 1].name,
|
||||||
zeroThrottleValue, zeroThrottleValue + 200);
|
zeroThrottleValue, zeroThrottleValue + 200);
|
||||||
|
|
||||||
$('#dialogMotorOutputReorder-closebtn').click(closeDialog);
|
$('#dialogMotorOutputReorder-closebtn').click(closeDialogMotorOutputReorder);
|
||||||
|
|
||||||
function closeDialog()
|
function closeDialogMotorOutputReorder()
|
||||||
{
|
{
|
||||||
domDialogMotorOutputReorder[0].close();
|
domDialogMotorOutputReorder[0].close();
|
||||||
motorOutputReorderComponent.close();
|
motorOutputReorderComponent.close();
|
||||||
|
@ -776,7 +773,7 @@ TABS.motors.initialize = function (callback) {
|
||||||
function onDocumentKeyPress(event)
|
function onDocumentKeyPress(event)
|
||||||
{
|
{
|
||||||
if (27 === event.which) {
|
if (27 === event.which) {
|
||||||
closeDialog();
|
closeDialogMotorOutputReorder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,6 +783,47 @@ TABS.motors.initialize = function (callback) {
|
||||||
domDialogMotorOutputReorder[0].showModal();
|
domDialogMotorOutputReorder[0].showModal();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SetupdescDshotDirectionDialog(callbackFunction, zeroThrottleValue)
|
||||||
|
{
|
||||||
|
const domEscDshotDirectionDialog = $('#escDshotDirectionDialog');
|
||||||
|
|
||||||
|
const idleThrottleValue = zeroThrottleValue + FC.PID_ADVANCED_CONFIG.digitalIdlePercent * 1000 / 100;
|
||||||
|
|
||||||
|
const motorConfig = {
|
||||||
|
numberOfMotors: self.numberOfValidOutputs,
|
||||||
|
motorStopValue: zeroThrottleValue,
|
||||||
|
motorSpinValue: idleThrottleValue,
|
||||||
|
escProtocolIsDshot: self.escProtocolIsDshot,
|
||||||
|
};
|
||||||
|
|
||||||
|
const escDshotDirectionComponent = new EscDshotDirectionComponent(
|
||||||
|
$('#escDshotDirectionDialog-Content'), callbackFunction, motorConfig);
|
||||||
|
|
||||||
|
$('#escDshotDirectionDialog-closebtn').on("click", closeEscDshotDirectionDialog);
|
||||||
|
|
||||||
|
function closeEscDshotDirectionDialog()
|
||||||
|
{
|
||||||
|
domEscDshotDirectionDialog[0].close();
|
||||||
|
escDshotDirectionComponent.close();
|
||||||
|
$(document).off("keydown", onDocumentKeyPress);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentKeyPress(event)
|
||||||
|
{
|
||||||
|
if (27 === event.which) {
|
||||||
|
closeEscDshotDirectionDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#escDshotDirectionDialog-Open').click(function()
|
||||||
|
{
|
||||||
|
$(document).on("keydown", onDocumentKeyPress);
|
||||||
|
domEscDshotDirectionDialog[0].showModal();
|
||||||
|
});
|
||||||
|
|
||||||
|
callbackFunction();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TABS.motors.cleanup = function (callback) {
|
TABS.motors.cleanup = function (callback) {
|
||||||
|
|
15
src/js/utils/CommonUtils.js
Normal file
15
src/js/utils/CommonUtils.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class CommonUtils
|
||||||
|
{
|
||||||
|
static GetMixerImageSrc(mixerIndex, reverseMotorDir, apiVersion)
|
||||||
|
{
|
||||||
|
let reverse = "";
|
||||||
|
|
||||||
|
if (semver.gte(apiVersion, API_VERSION_1_36)) {
|
||||||
|
reverse = reverseMotorDir ? "_reversed" : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return `./resources/motor_order/${mixerList[mixerIndex - 1].image}${reverse}.svg`;
|
||||||
|
}
|
||||||
|
}
|
40
src/js/utils/DshotCommand.js
Normal file
40
src/js/utils/DshotCommand.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class DshotCommand
|
||||||
|
{
|
||||||
|
static get ALL_MOTORS() { return 255; }
|
||||||
|
}
|
||||||
|
|
||||||
|
DshotCommand.dshotCommands_e = {
|
||||||
|
DSHOT_CMD_MOTOR_STOP: 0,
|
||||||
|
DSHOT_CMD_BEACON1: 1,
|
||||||
|
DSHOT_CMD_BEACON2: 2,
|
||||||
|
DSHOT_CMD_BEACON3: 3,
|
||||||
|
DSHOT_CMD_BEACON4: 4,
|
||||||
|
DSHOT_CMD_BEACON5: 5,
|
||||||
|
DSHOT_CMD_ESC_INFO: 6, // V2 includes settings
|
||||||
|
DSHOT_CMD_SPIN_DIRECTION_1: 7,
|
||||||
|
DSHOT_CMD_SPIN_DIRECTION_2: 8,
|
||||||
|
DSHOT_CMD_3D_MODE_OFF: 9,
|
||||||
|
DSHOT_CMD_3D_MODE_ON: 10,
|
||||||
|
DSHOT_CMD_SETTINGS_REQUEST: 11, // Currently not implemented
|
||||||
|
DSHOT_CMD_SAVE_SETTINGS: 12,
|
||||||
|
DSHOT_CMD_SPIN_DIRECTION_NORMAL: 20,
|
||||||
|
DSHOT_CMD_SPIN_DIRECTION_REVERSED: 21,
|
||||||
|
DSHOT_CMD_LED0_ON: 22, // BLHeli32 only
|
||||||
|
DSHOT_CMD_LED1_ON: 23, // BLHeli32 only
|
||||||
|
DSHOT_CMD_LED2_ON: 24, // BLHeli32 only
|
||||||
|
DSHOT_CMD_LED3_ON: 25, // BLHeli32 only
|
||||||
|
DSHOT_CMD_LED0_OFF: 26, // BLHeli32 only
|
||||||
|
DSHOT_CMD_LED1_OFF: 27, // BLHeli32 only
|
||||||
|
DSHOT_CMD_LED2_OFF: 28, // BLHeli32 only
|
||||||
|
DSHOT_CMD_LED3_OFF: 29, // BLHeli32 only
|
||||||
|
DSHOT_CMD_AUDIO_STREAM_MODE_ON_OFF: 30, // KISS audio Stream mode on/Off
|
||||||
|
DSHOT_CMD_SILENT_MODE_ON_OFF: 31, // KISS silent Mode on/Off
|
||||||
|
DSHOT_CMD_MAX: 47,
|
||||||
|
};
|
||||||
|
|
||||||
|
DshotCommand.dshotCommandType_e = {
|
||||||
|
DSHOT_CMD_TYPE_INLINE: 0, // dshot commands sent inline with motor signal (motors must be enabled)
|
||||||
|
DSHOT_CMD_TYPE_BLOCKING: 1, // dshot commands sent in blocking method (motors must be disabled)
|
||||||
|
};
|
95
src/js/utils/EscProtocols.js
Normal file
95
src/js/utils/EscProtocols.js
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class EscProtocols
|
||||||
|
{
|
||||||
|
static get PROTOCOL_PWM() { return "PWM"; }
|
||||||
|
static get PROTOCOL_ONESHOT125() { return "ONESHOT125"; }
|
||||||
|
static get PROTOCOL_ONESHOT42() { return "ONESHOT42"; }
|
||||||
|
static get PROTOCOL_MULTISHOT() { return "MULTISHOT"; }
|
||||||
|
static get PROTOCOL_BRUSHED() { return "BRUSHED"; }
|
||||||
|
static get PROTOCOL_DSHOT150() { return "DSHOT150"; }
|
||||||
|
static get PROTOCOL_DSHOT300() { return "DSHOT300"; }
|
||||||
|
static get PROTOCOL_DSHOT600() { return "DSHOT600"; }
|
||||||
|
static get PROTOCOL_DSHOT1200() { return "DSHOT1200"; }
|
||||||
|
static get PROTOCOL_PROSHOT1000() { return "PROSHOT1000"; }
|
||||||
|
static get PROTOCOL_DISABLED() { return "DISABLED"; }
|
||||||
|
|
||||||
|
static get DSHOT_PROTOCOLS_SET()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
EscProtocols.PROTOCOL_DSHOT150,
|
||||||
|
EscProtocols.PROTOCOL_DSHOT300,
|
||||||
|
EscProtocols.PROTOCOL_DSHOT600,
|
||||||
|
EscProtocols.PROTOCOL_DSHOT1200,
|
||||||
|
EscProtocols.PROTOCOL_PROSHOT1000,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static GetProtocolName(apiVersion, protocolIndex)
|
||||||
|
{
|
||||||
|
const escProtocols = EscProtocols.GetAvailableProtocols(apiVersion);
|
||||||
|
return escProtocols[protocolIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
static IsProtocolDshot(apiVersion, protocolIndex)
|
||||||
|
{
|
||||||
|
const protocolName = EscProtocols.GetProtocolName(apiVersion, protocolIndex);
|
||||||
|
return EscProtocols.DSHOT_PROTOCOLS_SET.includes(protocolName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GetAvailableProtocols(apiVersion)
|
||||||
|
{
|
||||||
|
const escProtocols = [
|
||||||
|
EscProtocols.PROTOCOL_PWM,
|
||||||
|
EscProtocols.PROTOCOL_ONESHOT125,
|
||||||
|
EscProtocols.PROTOCOL_ONESHOT42,
|
||||||
|
EscProtocols.PROTOCOL_MULTISHOT,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (semver.gte(apiVersion, "1.20.0")) {
|
||||||
|
escProtocols.push(EscProtocols.PROTOCOL_BRUSHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (semver.gte(apiVersion, API_VERSION_1_31)) {
|
||||||
|
escProtocols.push(EscProtocols.PROTOCOL_DSHOT150);
|
||||||
|
escProtocols.push(EscProtocols.PROTOCOL_DSHOT300);
|
||||||
|
escProtocols.push(EscProtocols.PROTOCOL_DSHOT600);
|
||||||
|
|
||||||
|
if (semver.lt(apiVersion, API_VERSION_1_42)) {
|
||||||
|
escProtocols.push(EscProtocols.PROTOCOL_DSHOT1200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (semver.gte(apiVersion, API_VERSION_1_36)) {
|
||||||
|
escProtocols.push(EscProtocols.PROTOCOL_PROSHOT1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (semver.gte(apiVersion, API_VERSION_1_43)) {
|
||||||
|
escProtocols.push(EscProtocols.PROTOCOL_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return escProtocols;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ReorderPwmProtocols(apiVersion, protocolIndex)
|
||||||
|
{
|
||||||
|
let result = protocolIndex;
|
||||||
|
|
||||||
|
if (semver.lt(apiVersion, "1.26.0")) {
|
||||||
|
switch (protocolIndex) {
|
||||||
|
case 5:
|
||||||
|
result = 7;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
result = 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -42,6 +42,7 @@
|
||||||
<link type="text/css" rel="stylesheet" href="./components/MotorOutputReordering/Styles.css" media="all"/>
|
<link type="text/css" rel="stylesheet" href="./components/MotorOutputReordering/Styles.css" media="all"/>
|
||||||
<link type="text/css" rel="stylesheet" href="./css/select2_custom.css" media="all"/>
|
<link type="text/css" rel="stylesheet" href="./css/select2_custom.css" media="all"/>
|
||||||
<link type="text/css" rel="stylesheet" href="./node_modules/select2/dist/css/select2.min.css" media="all"/>
|
<link type="text/css" rel="stylesheet" href="./node_modules/select2/dist/css/select2.min.css" media="all"/>
|
||||||
|
<link type="text/css" rel="stylesheet" href="./components/EscDshotDirection/Styles.css" media="all"/>
|
||||||
|
|
||||||
<link type="text/css" rel="stylesheet" href="./css/dark-theme.css" media="all" disabled/>
|
<link type="text/css" rel="stylesheet" href="./css/dark-theme.css" media="all" disabled/>
|
||||||
|
|
||||||
|
@ -72,6 +73,7 @@
|
||||||
<script type="text/javascript" src="./js/utils/common.js"></script>
|
<script type="text/javascript" src="./js/utils/common.js"></script>
|
||||||
<script type="text/javascript" src="./js/utils/css.js"></script>
|
<script type="text/javascript" src="./js/utils/css.js"></script>
|
||||||
<script type="text/javascript" src="./js/utils/window_watchers.js"></script>
|
<script type="text/javascript" src="./js/utils/window_watchers.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/utils/CommonUtils.js"></script>
|
||||||
<script type="text/javascript" src="./js/injected_methods.js"></script>
|
<script type="text/javascript" src="./js/injected_methods.js"></script>
|
||||||
<script type="text/javascript" src="./js/ConfigStorage.js"></script>
|
<script type="text/javascript" src="./js/ConfigStorage.js"></script>
|
||||||
<script type="text/javascript" src="./js/data_storage.js"></script>
|
<script type="text/javascript" src="./js/data_storage.js"></script>
|
||||||
|
@ -142,6 +144,11 @@
|
||||||
<script type="text/javascript" src="./components/MotorOutputReordering/MotorOutputReorderingCanvas.js"></script>
|
<script type="text/javascript" src="./components/MotorOutputReordering/MotorOutputReorderingCanvas.js"></script>
|
||||||
<script type="text/javascript" src="./components/MotorOutputReordering/MotorOutputReorderingConfig.js"></script>
|
<script type="text/javascript" src="./components/MotorOutputReordering/MotorOutputReorderingConfig.js"></script>
|
||||||
<script type="text/javascript" src="./node_modules/select2/dist/js/select2.min.js"></script>
|
<script type="text/javascript" src="./node_modules/select2/dist/js/select2.min.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/utils/EscProtocols.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/utils/DshotCommand.js"></script>
|
||||||
|
<script type="text/javascript" src="./components/EscDshotDirection/EscDshotDirectionComponent.js"></script>
|
||||||
|
<script type="text/javascript" src="./components/EscDshotDirection/EscDshotDirectionMotorDriver.js"></script>
|
||||||
|
<script type="text/javascript" src="./components/EscDshotDirection/EscDshotCommandQueue.js"></script>
|
||||||
|
|
||||||
<title></title>
|
<title></title>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -101,6 +101,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="power_info">
|
<div class="power_info">
|
||||||
<a href="#" id="motorOutputReorderDialogOpen" class="regular-button" i18n="motorOutputReorderDialogOpen"></a>
|
<a href="#" id="motorOutputReorderDialogOpen" class="regular-button" i18n="motorOutputReorderDialogOpen"></a>
|
||||||
|
<a href="#" id="escDshotDirectionDialog-Open" class="regular-button" i18n="escDshotDirectionDialog-Open"></a>
|
||||||
<span i18n="motorsVoltage" class="power_text"></span><span class="motors-bat-voltage power_value"></span>
|
<span i18n="motorsVoltage" class="power_text"></span><span class="motors-bat-voltage power_value"></span>
|
||||||
<span i18n="motorsADrawing" class="power_text"></span><span class="motors-bat-mah-drawing power_value"></span>
|
<span i18n="motorsADrawing" class="power_text"></span><span class="motors-bat-mah-drawing power_value"></span>
|
||||||
<span i18n="motorsmAhDrawn" class="power_text"></span><span class="motors-bat-mah-drawn power_value"></span>
|
<span i18n="motorsmAhDrawn" class="power_text"></span><span class="motors-bat-mah-drawn power_value"></span>
|
||||||
|
@ -200,4 +201,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
</div>
|
|
||||||
|
<dialog id="escDshotDirectionDialog">
|
||||||
|
<div id="escDshotDirectionDialog-ContentWrapper">
|
||||||
|
<div id="escDshotDirectionDialog-Content">
|
||||||
|
</div>
|
||||||
|
<a href="#" id="escDshotDirectionDialog-closebtn" class="regular-button right" i18n="close"></a>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue