mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-14 20:10:13 +03:00
Motor output reordering feature
Fixed Sonar warnings renaming MOTOR_REMAP to MOTOR_OUTPUT_REORDER<ING> Sonar warning fix Code style fixes after the code review moving styles to css from the motors tab dialog Dialog size of Androind devices Raneming MSP_<SET>_MOTOR_OUTPUT_REORDERING to MSP2 removing old styles and js files reference to motor_remap folder adding FC.* where needed to accomodate new master changes fixed alphabetical order for FC settings MOTOR_OUTPUT_REORDER css fix for Android for motor reordering dialog
This commit is contained in:
parent
b596c5fc76
commit
e4a85ccc2f
13 changed files with 930 additions and 3 deletions
|
@ -2537,6 +2537,40 @@
|
||||||
"message": "<strong>I understand the risks</strong>, the propellers are removed - enable motor control and arming, and disable Runaway Takeoff Prevention."
|
"message": "<strong>I understand the risks</strong>, the propellers are removed - enable motor control and arming, and disable Runaway Takeoff Prevention."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"motorOutputReorderDialogClose": {
|
||||||
|
"message": "Cancel"
|
||||||
|
},
|
||||||
|
"motorOutputReorderDialogAgree": {
|
||||||
|
"message": "Start"
|
||||||
|
},
|
||||||
|
"motorsRemapDialogTitle": {
|
||||||
|
"message": "Reorder motors"
|
||||||
|
},
|
||||||
|
"motorOutputReorderDialogOpen": {
|
||||||
|
"message": "Reorder motors"
|
||||||
|
},
|
||||||
|
"motorOutputReorderDialogSelectSpinningMotor": {
|
||||||
|
"message": "Click on the spinning motor..."
|
||||||
|
},
|
||||||
|
"motorOutputReorderDialogRemapIsDone": {
|
||||||
|
"message": "Ready! Check the motors spinning order by clicking on the image."
|
||||||
|
},
|
||||||
|
"motorsRemapDialogUnderstandRisks": {
|
||||||
|
"message": "<strong>I understand the risks</strong>,<br />the propellers are removed."
|
||||||
|
},
|
||||||
|
"motorsRemapDialogRiskNotice": {
|
||||||
|
"message": "<strong>Safety notice</strong><br /><strong class=\"message-negative\">Remove all propellers to prevent injury!</strong><br />The motors will <strong>spin up!</strong>"
|
||||||
|
},
|
||||||
|
"motorsRemapDialogExplanations": {
|
||||||
|
"message": "<strong>Information notice</strong><br />Motors will spin up one by one and you will be able to select which motor is spinning. The battery should be plugged in, correct ESC protocol should be selected. This utility can only re-arrange currently active motors. More complex re-mapping requires the CLI Resource command. Refer to this <a href=\"https://github.com/betaflight/betaflight/wiki/Betaflight-resource-remapping\" target=\"_blank\" rel=\"noopener noreferrer\">Wiki page</a>."
|
||||||
|
},
|
||||||
|
"motorsRemapDialogSave": {
|
||||||
|
"message": "Save"
|
||||||
|
},
|
||||||
|
"motorsRemapDialogStartOver": {
|
||||||
|
"message": "Start over"
|
||||||
|
},
|
||||||
|
|
||||||
"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."
|
||||||
},
|
},
|
||||||
|
|
30
src/Components/MotorOutputReordering/Body.html
Normal file
30
src/Components/MotorOutputReordering/Body.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<div class="motorOutputReorderComponent">
|
||||||
|
<h3 i18n="motorsRemapDialogTitle" class="motorOutputReorderComponentHeader"></h3>
|
||||||
|
<div class="componentContent" id="dialogMotorOutputReorderMainContent">
|
||||||
|
<canvas id="motorOutputReorderCanvas"></canvas>
|
||||||
|
<div id="motorOutputReorderActionPanel">
|
||||||
|
<h4 id="motorOutputReorderActionHint"></h4>
|
||||||
|
</div>
|
||||||
|
<div id="motorOutputReorderSaveStartOverButtonsPanel">
|
||||||
|
<a href="#" id="motorsRemapDialogSave" class="regular-button left" i18n="motorsRemapDialogSave"></a>
|
||||||
|
<a href="#" id="motorsRemapDialogStartOver" class="regular-button left" i18n="motorsRemapDialogStartOver"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="componentContent" id="dialogMotorOutputReorderWarning">
|
||||||
|
<div class="notice">
|
||||||
|
<p class="motorsRemapDialogRiskNoticeText" i18n="motorsRemapDialogRiskNotice"></p>
|
||||||
|
<div class="motorsRemapToggleParentContainer">
|
||||||
|
<div class="motorsRemapToggleNarrow">
|
||||||
|
<input id="motorsEnableTestMode-dialogMotorOutputReorder" type="checkbox" class="toggle"/>
|
||||||
|
</div>
|
||||||
|
<div class="motorsRemapToggleWide">
|
||||||
|
<span class="motorsEnableTestMode motorsRemapDialogRiskNoticeText" i18n="motorsRemapDialogUnderstandRisks"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="motorsRemapDialogRExplanationText" i18n="motorsRemapDialogExplanations"></div>
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="#" id="dialogMotorOutputReorderAgreeButton" class="regular-button" i18n="motorOutputReorderDialogAgree"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,269 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class MotorOutputReorderCanvas
|
||||||
|
{
|
||||||
|
constructor(canvas, droneConfiguration, motorClickCallback, spinMotorCallback)
|
||||||
|
{
|
||||||
|
this._spinMotorCallback = spinMotorCallback;
|
||||||
|
this._canvas = canvas;
|
||||||
|
this._motorClickCallback = motorClickCallback;
|
||||||
|
this._width = this._canvas.width();
|
||||||
|
this._height = this._canvas.height();
|
||||||
|
this._screenSize = Math.min(this._width, this._height);
|
||||||
|
|
||||||
|
this._config = new MotorOutputReorderConfig(this._screenSize);
|
||||||
|
|
||||||
|
// no component resize allowing yet
|
||||||
|
this._canvas.prop({
|
||||||
|
width: this._width,
|
||||||
|
height: this._height,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._droneConfiguration = droneConfiguration;
|
||||||
|
|
||||||
|
this._ctx = this._canvas[0].getContext("2d");
|
||||||
|
this._ctx.translate(this._width / 2, this._height / 2);
|
||||||
|
|
||||||
|
this._canvas.mousemove((event) =>
|
||||||
|
{
|
||||||
|
this._onMouseMove(event);
|
||||||
|
});
|
||||||
|
this._canvas.mouseleave(() =>
|
||||||
|
{
|
||||||
|
this._onMouseLeave();
|
||||||
|
});
|
||||||
|
this._canvas.mousedown(() =>
|
||||||
|
{
|
||||||
|
this._onMouseDown();
|
||||||
|
});
|
||||||
|
this._canvas.mouseup(() =>
|
||||||
|
{
|
||||||
|
this._onMouseUp(event);
|
||||||
|
});
|
||||||
|
this._canvas.click(() =>
|
||||||
|
{
|
||||||
|
this._onMouseClick();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.startOver();
|
||||||
|
}
|
||||||
|
|
||||||
|
pause()
|
||||||
|
{
|
||||||
|
this._keepDrawing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
startOver()
|
||||||
|
{
|
||||||
|
this.readyMotors = []; //motors that already being selected for remapping by user
|
||||||
|
this.remappingReady = false;
|
||||||
|
this._motorIndexToSpinOnMouseDown = -1;
|
||||||
|
this._keepDrawing = true;
|
||||||
|
this._mouse = {x : 0, y: 0};
|
||||||
|
window.requestAnimationFrame(() =>
|
||||||
|
{
|
||||||
|
this._drawOnce();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_drawOnce()
|
||||||
|
{
|
||||||
|
this._ctx.clearRect(-this._width / 2, -this._height / 2, this._width, this._height);
|
||||||
|
|
||||||
|
this._drawFrame();
|
||||||
|
this._drawDirectionArrow();
|
||||||
|
this._markMotors();
|
||||||
|
this._drawMotors();
|
||||||
|
|
||||||
|
if (this._keepDrawing) {
|
||||||
|
window.requestAnimationFrame(() =>
|
||||||
|
{
|
||||||
|
this._drawOnce();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onMouseDown()
|
||||||
|
{
|
||||||
|
if (this.remappingReady) {
|
||||||
|
this._motorIndexToSpinOnMouseDown = this._getMouseHoverMotorIndex();
|
||||||
|
|
||||||
|
if (this._spinMotorCallback) {
|
||||||
|
this._spinMotorCallback(this._motorIndexToSpinOnMouseDown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onMouseUp()
|
||||||
|
{
|
||||||
|
if (-1 !== this._motorIndexToSpinOnMouseDown) {
|
||||||
|
this._motorIndexToSpinOnMouseDown = -1;
|
||||||
|
|
||||||
|
if (this._spinMotorCallback) {
|
||||||
|
this._spinMotorCallback(this._motorIndexToSpinOnMouseDown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onMouseClick()
|
||||||
|
{
|
||||||
|
const motorIndex = this._getMouseHoverMotorIndex();
|
||||||
|
|
||||||
|
if (this._motorClickCallback && -1 !== motorIndex && !this.readyMotors.includes(motorIndex)) {
|
||||||
|
this._motorClickCallback(motorIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onMouseMove(event)
|
||||||
|
{
|
||||||
|
const boundingRect = this._canvas[0].getBoundingClientRect();
|
||||||
|
this._mouse.x = event.clientX - boundingRect.left - this._width / 2;
|
||||||
|
this._mouse.y = event.clientY - boundingRect.top - this._height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onMouseLeave()
|
||||||
|
{
|
||||||
|
this._mouse.x = Number.MIN_SAFE_INTEGER;
|
||||||
|
this._mouse.y = Number.MIN_SAFE_INTEGER;
|
||||||
|
|
||||||
|
if (-1 !== this._motorIndexToSpinOnMouseDown) {
|
||||||
|
this._motorIndexToSpinOnMouseDown = -1;
|
||||||
|
|
||||||
|
if (this._spinMotorCallback) {
|
||||||
|
this._spinMotorCallback(this._motorIndexToSpinOnMouseDown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_markMotors()
|
||||||
|
{
|
||||||
|
const motors = this._config[this._droneConfiguration].Motors;
|
||||||
|
const mouseHoverMotorIndex = this._getMouseHoverMotorIndex();
|
||||||
|
|
||||||
|
if (-1 === this._motorIndexToSpinOnMouseDown) {
|
||||||
|
for (let i = 0; i < this.readyMotors.length; i++) {
|
||||||
|
const motorIndex = this.readyMotors[i];
|
||||||
|
this._ctx.beginPath();
|
||||||
|
this._ctx.arc(motors[motorIndex].x, motors[motorIndex].y, this._config[this._droneConfiguration].PropRadius, 0, 2 * Math.PI);
|
||||||
|
this._ctx.closePath();
|
||||||
|
this._ctx.fillStyle = this._config.MotorReadyColor;
|
||||||
|
this._ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 !== mouseHoverMotorIndex && !this.readyMotors.includes(mouseHoverMotorIndex)) {
|
||||||
|
this._ctx.beginPath();
|
||||||
|
this._ctx.arc(motors[mouseHoverMotorIndex].x, motors[mouseHoverMotorIndex].y, this._config[this._droneConfiguration].PropRadius, 0, 2 * Math.PI);
|
||||||
|
this._ctx.closePath();
|
||||||
|
this._ctx.fillStyle = this._config.MotorMouseHoverColor;
|
||||||
|
this._ctx.fill();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const spinningMotor = this._motorIndexToSpinOnMouseDown;
|
||||||
|
|
||||||
|
for (let i = 0; i < motors.length; i++) {
|
||||||
|
this._ctx.fillStyle = this._config.MotorReadyColor;
|
||||||
|
if (spinningMotor === i) {
|
||||||
|
this._ctx.fillStyle = this._config.MotorSpinningColor;
|
||||||
|
} else if (mouseHoverMotorIndex === i) {
|
||||||
|
this._ctx.fillStyle = this._config.MotorMouseHoverColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ctx.beginPath();
|
||||||
|
this._ctx.arc(motors[i].x, motors[i].y, this._config[this._droneConfiguration].PropRadius, 0, 2 * Math.PI);
|
||||||
|
this._ctx.closePath();
|
||||||
|
this._ctx.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_getMouseHoverMotorIndex()
|
||||||
|
{
|
||||||
|
const x = this._mouse.x;
|
||||||
|
const y = this._mouse.y;
|
||||||
|
|
||||||
|
let result = -1;
|
||||||
|
let currentDist = Number.MAX_SAFE_INTEGER;
|
||||||
|
const motors = this._config[this._droneConfiguration].Motors;
|
||||||
|
|
||||||
|
for (let i = 0; i < motors.length; i++) {
|
||||||
|
const dist = Math.sqrt((x - motors[i].x) * (x - motors[i].x) + (y - motors[i].y) * (y - motors[i].y));
|
||||||
|
|
||||||
|
if (dist < this._config[this._droneConfiguration].PropRadius && dist < currentDist) {
|
||||||
|
currentDist = dist;
|
||||||
|
result = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_drawMotors()
|
||||||
|
{
|
||||||
|
|
||||||
|
this._ctx.lineWidth = this._config.PropEdgeLineWidth;
|
||||||
|
this._ctx.strokeStyle = this._config.PropEdgeColor;
|
||||||
|
const motors = this._config[this._droneConfiguration].Motors;
|
||||||
|
|
||||||
|
for (let i = 0; i < motors.length; i++) {
|
||||||
|
this._ctx.beginPath();
|
||||||
|
this._ctx.arc(motors[i].x, motors[i].y, this._config[this._droneConfiguration].PropRadius, 0, 2 * Math.PI);
|
||||||
|
this._ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_drawDirectionArrow()
|
||||||
|
{
|
||||||
|
this._ctx.beginPath();
|
||||||
|
this._ctx.moveTo(this._config.DirectionArrowPoints[0].x, this._config.DirectionArrowPoints[0].y);
|
||||||
|
|
||||||
|
for (let i = 1; i < this._config.DirectionArrowPoints.length; i++) {
|
||||||
|
this._ctx.lineTo(this._config.DirectionArrowPoints[i].x, this._config.DirectionArrowPoints[i].y);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ctx.closePath();
|
||||||
|
this._ctx.fillStyle = this._config.ArrowColor;
|
||||||
|
this._ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
_drawFrame()
|
||||||
|
{
|
||||||
|
this._ctx.beginPath();
|
||||||
|
this._ctx.lineWidth = this._config[this._droneConfiguration].ArmWidth;
|
||||||
|
this._ctx.lineCap = "round";
|
||||||
|
this._ctx.strokeStyle = this._config.FrameColor;
|
||||||
|
const motors = this._config[this._droneConfiguration].Motors;
|
||||||
|
|
||||||
|
switch(this._droneConfiguration) {
|
||||||
|
case "Quad X":
|
||||||
|
case "Quad +":
|
||||||
|
this._ctx.moveTo(motors[0].x, motors[0].y);
|
||||||
|
this._ctx.lineTo(motors[3].x, motors[3].y);
|
||||||
|
this._ctx.moveTo(motors[1].x, motors[1].y);
|
||||||
|
this._ctx.lineTo(motors[2].x, motors[2].y);
|
||||||
|
break;
|
||||||
|
case "Quad X 1234":
|
||||||
|
this._ctx.moveTo(motors[0].x, motors[0].y);
|
||||||
|
this._ctx.lineTo(motors[2].x, motors[2].y);
|
||||||
|
this._ctx.moveTo(motors[3].x, motors[3].y);
|
||||||
|
this._ctx.lineTo(motors[1].x, motors[1].y);
|
||||||
|
break;
|
||||||
|
case "Tricopter":
|
||||||
|
this._ctx.moveTo(motors[1].x, motors[1].y);
|
||||||
|
this._ctx.lineTo(motors[2].x, motors[2].y);
|
||||||
|
this._ctx.moveTo(motors[0].x, motors[0].y);
|
||||||
|
this._ctx.lineTo(motors[0].x, motors[2].y);
|
||||||
|
break;
|
||||||
|
case "Hex +":
|
||||||
|
case "Hex X":
|
||||||
|
this._ctx.moveTo(motors[0].x, motors[0].y);
|
||||||
|
this._ctx.lineTo(motors[3].x, motors[3].y);
|
||||||
|
this._ctx.moveTo(motors[1].x, motors[1].y);
|
||||||
|
this._ctx.lineTo(motors[2].x, motors[2].y);
|
||||||
|
this._ctx.moveTo(motors[4].x, motors[4].y);
|
||||||
|
this._ctx.lineTo(motors[5].x, motors[5].y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,258 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class MotorOutputReorderComponent
|
||||||
|
{
|
||||||
|
constructor(contentDiv, onLoadedCallback, droneConfiguration, motorStopValue, motorSpinValue)
|
||||||
|
{
|
||||||
|
this._contentDiv = contentDiv;
|
||||||
|
this._onLoadedCallback = onLoadedCallback;
|
||||||
|
this._droneConfiguration = droneConfiguration;
|
||||||
|
this._motorStopValue = motorStopValue;
|
||||||
|
this._motorSpinValue = motorSpinValue;
|
||||||
|
this._config = new MotorOutputReorderConfig(100);
|
||||||
|
|
||||||
|
this._currentJerkingTimeout = -1;
|
||||||
|
this._currentJerkingMotor = -1;
|
||||||
|
|
||||||
|
this._currentSpinningMotor = -1;
|
||||||
|
|
||||||
|
this._contentDiv.load("./Components/MotorOutputReordering/Body.html", () =>
|
||||||
|
{
|
||||||
|
this._setupdialog();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_readDom()
|
||||||
|
{
|
||||||
|
this._domAgreeSafetyCheckBox = $('#motorsEnableTestMode-dialogMotorOutputReorder');
|
||||||
|
this._domAgreeButton = $('#dialogMotorOutputReorderAgreeButton');
|
||||||
|
this._domStartOverButton = $('#motorsRemapDialogStartOver');
|
||||||
|
this._domSaveButton = $('#motorsRemapDialogSave');
|
||||||
|
this._domMainContentBlock = $('#dialogMotorOutputReorderMainContent');
|
||||||
|
this._domWarningContentBlock = $('#dialogMotorOutputReorderWarning');
|
||||||
|
this._domActionHintBlock = $('#motorOutputReorderActionHint');
|
||||||
|
this._domCanvas = $('#motorOutputReorderCanvas');
|
||||||
|
}
|
||||||
|
|
||||||
|
_setupdialog()
|
||||||
|
{
|
||||||
|
i18n.localizePage();
|
||||||
|
this._readDom();
|
||||||
|
|
||||||
|
this._resetGui();
|
||||||
|
|
||||||
|
this._domAgreeSafetyCheckBox.change(() =>
|
||||||
|
{
|
||||||
|
const enabled = this._domAgreeSafetyCheckBox.is(':checked');
|
||||||
|
this._domAgreeButton.toggle(enabled);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._domAgreeButton.click(() =>
|
||||||
|
{
|
||||||
|
this._onAgreeButtonClicked();
|
||||||
|
});
|
||||||
|
this._domStartOverButton.click(() =>
|
||||||
|
{
|
||||||
|
this._startOver();
|
||||||
|
});
|
||||||
|
this._domSaveButton.click(() =>
|
||||||
|
{
|
||||||
|
this._save();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._onLoadedCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
close()
|
||||||
|
{
|
||||||
|
this._stopAnyMotorJerking();
|
||||||
|
this._stopMotor();
|
||||||
|
this._stopUserInteraction();
|
||||||
|
this._resetGui();
|
||||||
|
}
|
||||||
|
|
||||||
|
_resetGui()
|
||||||
|
{
|
||||||
|
this._domMainContentBlock.hide();
|
||||||
|
this._domWarningContentBlock.show();
|
||||||
|
this._domAgreeButton.hide();
|
||||||
|
|
||||||
|
this._domAgreeSafetyCheckBox.prop('checked', false);
|
||||||
|
this._domAgreeSafetyCheckBox.change();
|
||||||
|
this._showSaveStartOverButtons(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_save()
|
||||||
|
{
|
||||||
|
function save_to_eeprom()
|
||||||
|
{
|
||||||
|
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, reboot);
|
||||||
|
}
|
||||||
|
|
||||||
|
function reboot()
|
||||||
|
{
|
||||||
|
GUI.log(i18n.getMessage('configurationEepromSaved'));
|
||||||
|
|
||||||
|
GUI.tab_switch_cleanup(function()
|
||||||
|
{
|
||||||
|
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false);
|
||||||
|
reinitialiseConnection(self);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
FC.MOTOR_OUTPUT_ORDER = Array.from(this._newMotorOutputReorder);
|
||||||
|
|
||||||
|
MSP.send_message(MSPCodes.MSP2_SET_MOTOR_OUTPUT_REORDERING, mspHelper.crunch(MSPCodes.MSP2_SET_MOTOR_OUTPUT_REORDERING));
|
||||||
|
|
||||||
|
save_to_eeprom();
|
||||||
|
}
|
||||||
|
|
||||||
|
_calculateNewMotorOutputReorder()
|
||||||
|
{
|
||||||
|
this._newMotorOutputReorder = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < this.motorOutputReorderCanvas.readyMotors.length; i++) {
|
||||||
|
this._newMotorOutputReorder.push(this._remapMotorIndex(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_remapMotorIndex(motorIndex)
|
||||||
|
{
|
||||||
|
return FC.MOTOR_OUTPUT_ORDER[this.motorOutputReorderCanvas.readyMotors.indexOf(motorIndex)];
|
||||||
|
}
|
||||||
|
|
||||||
|
_startOver()
|
||||||
|
{
|
||||||
|
this._showSaveStartOverButtons(false);
|
||||||
|
this._startUserInteraction();
|
||||||
|
}
|
||||||
|
|
||||||
|
_showSaveStartOverButtons(show)
|
||||||
|
{
|
||||||
|
if (show) {
|
||||||
|
this._domStartOverButton.show();
|
||||||
|
this._domSaveButton.show();
|
||||||
|
} else {
|
||||||
|
this._domStartOverButton.hide();
|
||||||
|
this._domSaveButton.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onAgreeButtonClicked()
|
||||||
|
{
|
||||||
|
this._domActionHintBlock.text(i18n.getMessage("motorOutputReorderDialogSelectSpinningMotor"));
|
||||||
|
this._domWarningContentBlock.hide();
|
||||||
|
this._domMainContentBlock.show();
|
||||||
|
this._startUserInteraction();
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopUserInteraction()
|
||||||
|
{
|
||||||
|
if (this.motorOutputReorderCanvas) {
|
||||||
|
this.motorOutputReorderCanvas.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_startUserInteraction()
|
||||||
|
{
|
||||||
|
if (this.motorOutputReorderCanvas) {
|
||||||
|
this.motorOutputReorderCanvas.startOver();
|
||||||
|
} else {
|
||||||
|
this.motorOutputReorderCanvas = new MotorOutputReorderCanvas(this._domCanvas,
|
||||||
|
this._droneConfiguration,
|
||||||
|
(motorIndex) =>
|
||||||
|
{ // motor click callback
|
||||||
|
this._onMotorClick(motorIndex);
|
||||||
|
},
|
||||||
|
(motorIndex) =>
|
||||||
|
{ // motor spin callback
|
||||||
|
let indexToSpin = -1;
|
||||||
|
|
||||||
|
if (-1 !== motorIndex) {
|
||||||
|
indexToSpin = this.motorOutputReorderCanvas.readyMotors.indexOf(motorIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._spinMotor(indexToSpin);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._startMotorJerking(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopAnyMotorJerking()
|
||||||
|
{
|
||||||
|
if (-1 !== this._currentJerkingTimeout) {
|
||||||
|
clearTimeout(this._currentJerkingTimeout);
|
||||||
|
this._currentJerkingTimeout = -1;
|
||||||
|
this._spinMotor(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._currentJerkingMotor = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_startMotorJerking(motorIndex)
|
||||||
|
{
|
||||||
|
this._stopAnyMotorJerking();
|
||||||
|
this._currentJerkingMotor = motorIndex;
|
||||||
|
this._motorStartTimeout(motorIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
_motorStartTimeout(motorIndex)
|
||||||
|
{
|
||||||
|
this._spinMotor(motorIndex);
|
||||||
|
this._currentJerkingTimeout = setTimeout(() =>
|
||||||
|
{
|
||||||
|
this._motorStopTimeout(motorIndex);
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
_motorStopTimeout(motorIndex)
|
||||||
|
{
|
||||||
|
this._spinMotor(-1);
|
||||||
|
this._currentJerkingTimeout = setTimeout(() =>
|
||||||
|
{
|
||||||
|
this._motorStartTimeout(motorIndex);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_spinMotor(motorIndex)
|
||||||
|
{
|
||||||
|
this._currentSpinningMotor = motorIndex;
|
||||||
|
const buffer = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < this._config[this._droneConfiguration].Motors.length; i++) {
|
||||||
|
if (i === motorIndex) {
|
||||||
|
buffer.push16(this._motorSpinValue);
|
||||||
|
} else {
|
||||||
|
buffer.push16(this._motorStopValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MSP.send_message(MSPCodes.MSP_SET_MOTOR, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopMotor()
|
||||||
|
{
|
||||||
|
if (-1 !== this._currentSpinningMotor) {
|
||||||
|
this._spinMotor(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onMotorClick(motorIndex)
|
||||||
|
{
|
||||||
|
this.motorOutputReorderCanvas.readyMotors.push(motorIndex);
|
||||||
|
this._currentJerkingMotor ++;
|
||||||
|
|
||||||
|
if (this._currentJerkingMotor < this._config[this._droneConfiguration].Motors.length) {
|
||||||
|
this._startMotorJerking(this._currentJerkingMotor);
|
||||||
|
} else {
|
||||||
|
this._stopAnyMotorJerking();
|
||||||
|
this._domActionHintBlock.text(i18n.getMessage("motorOutputReorderDialogRemapIsDone"));
|
||||||
|
this._calculateNewMotorOutputReorder();
|
||||||
|
this.motorOutputReorderCanvas.remappingReady = true;
|
||||||
|
this._showSaveStartOverButtons(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function MotorOutputReorderConfig(screenSize)
|
||||||
|
{
|
||||||
|
this.FrameColor = 'rgb(186, 186, 186)';
|
||||||
|
this.PropEdgeColor = 'rgb(255, 187, 0)';
|
||||||
|
this.PropEdgeLineWidth = 3;
|
||||||
|
this.MotorNumberTextFont = `${screenSize * 0.1}px 'Open Sans', 'Segoe UI', Tahoma, sans-serif`;
|
||||||
|
this.MotorNumberTextColor = 'rgb(0, 0, 0)';
|
||||||
|
this.MotorMouseHoverColor = 'rgba(255, 187, 0, 0.4)';
|
||||||
|
this.MotorSpinningColor = 'rgba(255, 0, 0, 0.4)';
|
||||||
|
this.MotorReadyColor = 'rgba(0,128,0,0.4)';
|
||||||
|
|
||||||
|
this.ArrowColor = 'rgb(182,67,67)';
|
||||||
|
this.DirectionArrowPoints = [
|
||||||
|
{x: -0.03 * screenSize, y: 0.11 * screenSize},
|
||||||
|
{x: -0.03 * screenSize, y: -0.01 * screenSize},
|
||||||
|
{x: -0.07 * screenSize, y: -0.01 * screenSize},
|
||||||
|
{x: 0.0 * screenSize, y: -0.13 * screenSize},
|
||||||
|
{x: 0.07 * screenSize, y: -0.01 * screenSize},
|
||||||
|
{x: 0.03 * screenSize, y: -0.01 * screenSize},
|
||||||
|
{x: 0.03 * screenSize, y: 0.11 * screenSize},
|
||||||
|
];
|
||||||
|
|
||||||
|
//===========================================
|
||||||
|
let frameRaduis = 0.28 * screenSize;
|
||||||
|
this["Quad X"] =
|
||||||
|
{
|
||||||
|
PropRadius: 0.2 * screenSize,
|
||||||
|
ArmWidth: 0.1 * screenSize,
|
||||||
|
Motors:
|
||||||
|
[
|
||||||
|
{x: frameRaduis, y: frameRaduis},
|
||||||
|
{x: frameRaduis, y: -frameRaduis},
|
||||||
|
{x: -frameRaduis, y: frameRaduis},
|
||||||
|
{x: -frameRaduis, y: -frameRaduis},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
//===========================================
|
||||||
|
frameRaduis = 0.28 * screenSize;
|
||||||
|
this["Quad X 1234"] =
|
||||||
|
{
|
||||||
|
PropRadius: 0.2 * screenSize,
|
||||||
|
ArmWidth: 0.1 * screenSize,
|
||||||
|
Motors:
|
||||||
|
[
|
||||||
|
{x: -frameRaduis, y: -frameRaduis},
|
||||||
|
{x: frameRaduis, y: -frameRaduis},
|
||||||
|
{x: frameRaduis, y: frameRaduis},
|
||||||
|
{x: -frameRaduis, y: frameRaduis},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
//===========================================
|
||||||
|
frameRaduis = 0.32 * screenSize;
|
||||||
|
this["Quad +"] =
|
||||||
|
{
|
||||||
|
PropRadius: 0.15 * screenSize,
|
||||||
|
ArmWidth: 0.1 * screenSize,
|
||||||
|
Motors:
|
||||||
|
[
|
||||||
|
{x: 0, y: frameRaduis},
|
||||||
|
{x: frameRaduis, y: 0 },
|
||||||
|
{x: -frameRaduis, y: 0 },
|
||||||
|
{x: 0, y: -frameRaduis},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
//===========================================
|
||||||
|
frameRaduis = 0.30 * screenSize;
|
||||||
|
this["Tricopter"] =
|
||||||
|
{
|
||||||
|
PropRadius: 0.15 * screenSize,
|
||||||
|
ArmWidth: 0.1 * screenSize,
|
||||||
|
Motors:
|
||||||
|
[
|
||||||
|
{x: 0, y: frameRaduis},
|
||||||
|
{x: frameRaduis, y: -frameRaduis},
|
||||||
|
{x: -frameRaduis, y: -frameRaduis},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
//===========================================
|
||||||
|
frameRaduis = 0.35 * screenSize;
|
||||||
|
this["Hex +"] =
|
||||||
|
{
|
||||||
|
PropRadius: 0.14 * screenSize,
|
||||||
|
ArmWidth: 0.1 * screenSize,
|
||||||
|
Motors: [],
|
||||||
|
};
|
||||||
|
let dAngle = Math.PI / 3;
|
||||||
|
let angle = 0;
|
||||||
|
|
||||||
|
angle = dAngle * 1;
|
||||||
|
this["Hex +"].Motors.push({x: Math.sin(angle) * frameRaduis, y: Math.cos(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = dAngle * 2;
|
||||||
|
this["Hex +"].Motors.push({x: Math.sin(angle) * frameRaduis, y: Math.cos(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = -dAngle * 1;
|
||||||
|
this["Hex +"].Motors.push({x: Math.sin(angle) * frameRaduis, y: Math.cos(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = -dAngle * 2;
|
||||||
|
this["Hex +"].Motors.push({x: Math.sin(angle) * frameRaduis, y: Math.cos(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = dAngle * 3;
|
||||||
|
this["Hex +"].Motors.push({x: Math.sin(angle) * frameRaduis, y: Math.cos(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = dAngle * 0;
|
||||||
|
this["Hex +"].Motors.push({x: Math.sin(angle) * frameRaduis, y: Math.cos(angle) * frameRaduis});
|
||||||
|
|
||||||
|
//===========================================
|
||||||
|
frameRaduis = 0.35 * screenSize;
|
||||||
|
this["Hex X"] =
|
||||||
|
{
|
||||||
|
PropRadius: 0.14 * screenSize,
|
||||||
|
ArmWidth: 0.1 * screenSize,
|
||||||
|
Motors: [],
|
||||||
|
};
|
||||||
|
dAngle = Math.PI / 3;
|
||||||
|
|
||||||
|
angle = dAngle * 1;
|
||||||
|
this["Hex X"].Motors.push({x: Math.cos(angle) * frameRaduis, y: Math.sin(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = -dAngle * 1;
|
||||||
|
this["Hex X"].Motors.push({x: Math.cos(angle) * frameRaduis, y: Math.sin(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = dAngle * 2;
|
||||||
|
this["Hex X"].Motors.push({x: Math.cos(angle) * frameRaduis, y: Math.sin(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = -dAngle * 2;
|
||||||
|
this["Hex X"].Motors.push({x: Math.cos(angle) * frameRaduis, y: Math.sin(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = dAngle * 0;
|
||||||
|
this["Hex X"].Motors.push({x: Math.cos(angle) * frameRaduis, y: Math.sin(angle) * frameRaduis});
|
||||||
|
|
||||||
|
angle = dAngle * 3;
|
||||||
|
this["Hex X"].Motors.push({x: Math.cos(angle) * frameRaduis, y: Math.sin(angle) * frameRaduis});
|
||||||
|
}
|
72
src/Components/MotorOutputReordering/Styles.css
Normal file
72
src/Components/MotorOutputReordering/Styles.css
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
.motorOutputReorderComponent {
|
||||||
|
display:flex;
|
||||||
|
height:100%;
|
||||||
|
flex-flow:column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.motorOutputReorderComponentHeader {
|
||||||
|
border-bottom: 1px solid var(--accent);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dialogMotorOutputReorderMainContent {
|
||||||
|
display:flex;
|
||||||
|
height:100%;
|
||||||
|
flex-flow:column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dialogMotorOutputReorderWarning {
|
||||||
|
display:flex;
|
||||||
|
height:100%;
|
||||||
|
flex-flow:column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#motorOutputReorderCanvas {
|
||||||
|
width:100%;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#motorOutputReorderActionPanel {
|
||||||
|
height: 46px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dialogMotorOutputReorderSave {
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.motorsRemapToggleParentContainer {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#motorOutputReorderActionHint {
|
||||||
|
margin-top: 1.0em;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.motorsRemapToggleNarrow {
|
||||||
|
margin-right: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.motorsRemapToggleWide {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.motorsRemapDialogRiskNoticeText {
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.motorsRemapDialogRExplanationText {
|
||||||
|
font-size: 1.0em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#motorOutputReorderSaveStartOverButtonsPanel {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 4px;
|
||||||
|
}
|
|
@ -18,6 +18,27 @@
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-motors #dialogMotorOutputReorder-closebtn {
|
||||||
|
margin-right: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-motors #dialogMotorOutputReorder {
|
||||||
|
width: 400px;
|
||||||
|
height:440px
|
||||||
|
;}
|
||||||
|
|
||||||
|
.tab-motors #dialogMotorOutputReorderContentWrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-motors #dialogMotorOutputReorderContent {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-motors .mixerPreview img {
|
.tab-motors .mixerPreview img {
|
||||||
width: 120px;
|
width: 120px;
|
||||||
height: 120px;
|
height: 120px;
|
||||||
|
@ -424,4 +445,15 @@
|
||||||
.tab-motors .motor_testing .telemetry li {
|
.tab-motors .motor_testing .telemetry li {
|
||||||
font-size: 6px;
|
font-size: 6px;
|
||||||
}
|
}
|
||||||
|
.tab-motors #dialogMotorOutputReorder {
|
||||||
|
position: fixed;
|
||||||
|
width: calc(100% - 2em);
|
||||||
|
bottom: 0;
|
||||||
|
top: 56px;
|
||||||
|
border-radius: unset;
|
||||||
|
border: none;
|
||||||
|
overflow: auto;
|
||||||
|
margin: 0;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ const FC = {
|
||||||
MOTOR_3D_CONFIG: null,
|
MOTOR_3D_CONFIG: null,
|
||||||
MOTOR_CONFIG: null,
|
MOTOR_CONFIG: null,
|
||||||
MOTOR_DATA: null,
|
MOTOR_DATA: null,
|
||||||
|
MOTOR_OUTPUT_ORDER: null,
|
||||||
MOTOR_TELEMETRY_DATA: null,
|
MOTOR_TELEMETRY_DATA: null,
|
||||||
MULTIPLE_MSP: null,
|
MULTIPLE_MSP: null,
|
||||||
PID: null,
|
PID: null,
|
||||||
|
@ -605,6 +606,8 @@ const FC = {
|
||||||
vtxtable_powerlevel_label: 0,
|
vtxtable_powerlevel_label: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.MOTOR_OUTPUT_ORDER = [];
|
||||||
|
|
||||||
this.MULTIPLE_MSP = {
|
this.MULTIPLE_MSP = {
|
||||||
msp_commands: [],
|
msp_commands: [],
|
||||||
};
|
};
|
||||||
|
|
|
@ -179,4 +179,6 @@ var MSPCodes = {
|
||||||
|
|
||||||
// MSPv2 Betaflight specific
|
// MSPv2 Betaflight specific
|
||||||
MSP2_BETAFLIGHT_BIND: 0x3000,
|
MSP2_BETAFLIGHT_BIND: 0x3000,
|
||||||
|
MSP2_MOTOR_OUTPUT_REORDERING: 0x3001,
|
||||||
|
MSP2_SET_MOTOR_OUTPUT_REORDERING: 0x3002,
|
||||||
};
|
};
|
||||||
|
|
|
@ -147,6 +147,13 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
||||||
FC.MOTOR_DATA[i] = data.readU16();
|
FC.MOTOR_DATA[i] = data.readU16();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MSPCodes.MSP2_MOTOR_OUTPUT_REORDERING:
|
||||||
|
FC.MOTOR_OUTPUT_ORDER = [];
|
||||||
|
const arraySize = data.read8();
|
||||||
|
for (let i = 0; i < arraySize; i++) {
|
||||||
|
FC.MOTOR_OUTPUT_ORDER[i] = data.readU8();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MSPCodes.MSP_MOTOR_TELEMETRY:
|
case MSPCodes.MSP_MOTOR_TELEMETRY:
|
||||||
var telemMotorCount = data.readU8();
|
var telemMotorCount = data.readU8();
|
||||||
for (let i = 0; i < telemMotorCount; i++) {
|
for (let i = 0; i < telemMotorCount; i++) {
|
||||||
|
@ -1549,6 +1556,9 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
||||||
case MSPCodes.MSP_SET_RTC:
|
case MSPCodes.MSP_SET_RTC:
|
||||||
console.log('Real time clock set');
|
console.log('Real time clock set');
|
||||||
break;
|
break;
|
||||||
|
case MSPCodes.MSP2_SET_MOTOR_OUTPUT_REORDERING:
|
||||||
|
console.log('Motor output reordering set');
|
||||||
|
break;
|
||||||
|
|
||||||
case MSPCodes.MSP_MULTIPLE_MSP:
|
case MSPCodes.MSP_MULTIPLE_MSP:
|
||||||
|
|
||||||
|
@ -2249,6 +2259,15 @@ MspHelper.prototype.crunch = function(code) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSPCodes.MSP2_SET_MOTOR_OUTPUT_REORDERING:
|
||||||
|
|
||||||
|
buffer.push8(FC.MOTOR_OUTPUT_ORDER.length);
|
||||||
|
for (let i = 0; i < FC.MOTOR_OUTPUT_ORDER.length; i++) {
|
||||||
|
buffer.push8(FC.MOTOR_OUTPUT_ORDER[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,11 @@ TABS.motors.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function load_esc_protocol() {
|
function load_esc_protocol() {
|
||||||
MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, load_motor_data);
|
MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, load_motor_output_reordering);
|
||||||
|
}
|
||||||
|
|
||||||
|
function load_motor_output_reordering() {
|
||||||
|
MSP.send_message(MSPCodes.MSP2_MOTOR_OUTPUT_REORDERING, false, false, load_motor_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function load_motor_data() {
|
function load_motor_data() {
|
||||||
|
@ -222,6 +226,13 @@ TABS.motors.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.mixerPreview img').attr('src', './resources/motor_order/' + mixerList[mixer - 1].image + reverse + '.svg');
|
$('.mixerPreview img').attr('src', './resources/motor_order/' + mixerList[mixer - 1].image + reverse + '.svg');
|
||||||
|
|
||||||
|
const motorOutputReorderConfig = new MotorOutputReorderConfig(100);
|
||||||
|
const domMotorOutputReorderDialogOpen = $('#motorOutputReorderDialogOpen');
|
||||||
|
|
||||||
|
const isMotorReorderingAvailable = (mixerList[mixer - 1].name in motorOutputReorderConfig)
|
||||||
|
&& (FC.MOTOR_OUTPUT_ORDER) && (FC.MOTOR_OUTPUT_ORDER.length > 0);
|
||||||
|
domMotorOutputReorderDialogOpen.toggle(isMotorReorderingAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
function process_html() {
|
function process_html() {
|
||||||
|
@ -726,7 +737,50 @@ TABS.motors.initialize = function (callback) {
|
||||||
// enable Status and Motor data pulling
|
// enable Status and Motor data pulling
|
||||||
GUI.interval_add('motor_and_status_pull', get_status, 50, true);
|
GUI.interval_add('motor_and_status_pull', get_status, 50, true);
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
let zeroThrottleValue = rangeMin;
|
||||||
|
|
||||||
|
if (self.feature3DEnabled) {
|
||||||
|
zeroThrottleValue = neutral3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_motor_output_reordering_dialog(content_ready, zeroThrottleValue);
|
||||||
|
|
||||||
|
function content_ready() {
|
||||||
|
GUI.content_ready(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
GUI.content_ready(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup_motor_output_reordering_dialog(callbackFunction, zeroThrottleValue)
|
||||||
|
{
|
||||||
|
const domDialogMotorOutputReorder = $('#dialogMotorOutputReorder');
|
||||||
|
|
||||||
|
const motorOutputReorderComponent = new MotorOutputReorderComponent($('#dialogMotorOutputReorderContent'),
|
||||||
|
callbackFunction, mixerList[FC.MIXER_CONFIG.mixer - 1].name,
|
||||||
|
zeroThrottleValue, zeroThrottleValue + 200);
|
||||||
|
|
||||||
|
$('#dialogMotorOutputReorder-closebtn').click(closeDialog);
|
||||||
|
|
||||||
|
function closeDialog()
|
||||||
|
{
|
||||||
|
domDialogMotorOutputReorder[0].close();
|
||||||
|
motorOutputReorderComponent.close();
|
||||||
|
$(document).off("keydown", onDocumentKeyPress);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentKeyPress(event)
|
||||||
|
{
|
||||||
|
if (27 === event.which) {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#motorOutputReorderDialogOpen').click(function()
|
||||||
|
{
|
||||||
|
$(document).on("keydown", onDocumentKeyPress);
|
||||||
|
domDialogMotorOutputReorder[0].showModal();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
<link type="text/css" rel="stylesheet" href="./css/dropdown-lists/css/style_lists.css" media="all"/>
|
<link type="text/css" rel="stylesheet" href="./css/dropdown-lists/css/style_lists.css" media="all"/>
|
||||||
<link type="text/css" rel="stylesheet" href="./js/libraries/switchery/switchery.css" media="all"/>
|
<link type="text/css" rel="stylesheet" href="./js/libraries/switchery/switchery.css" media="all"/>
|
||||||
<link type="text/css" rel="stylesheet" href="./node_modules/@fortawesome/fontawesome-free/css/all.css" media="all"/>
|
<link type="text/css" rel="stylesheet" href="./node_modules/@fortawesome/fontawesome-free/css/all.css" media="all"/>
|
||||||
|
<link type="text/css" rel="stylesheet" href="./Components/MotorOutputReordering/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/>
|
||||||
|
|
||||||
|
@ -135,6 +136,9 @@
|
||||||
<script type="text/javascript" src="./js/TuningSliders.js"></script>
|
<script type="text/javascript" src="./js/TuningSliders.js"></script>
|
||||||
<script type="text/javascript" src="./js/phones_ui.js"></script>
|
<script type="text/javascript" src="./js/phones_ui.js"></script>
|
||||||
<script type="text/javascript" src="./node_modules/jquery-touchswipe/jquery.touchSwipe.min.js"></script>
|
<script type="text/javascript" src="./node_modules/jquery-touchswipe/jquery.touchSwipe.min.js"></script>
|
||||||
|
<script type="text/javascript" src="./Components/MotorOutputReordering/MotorOutputReorderingComponent.js"></script>
|
||||||
|
<script type="text/javascript" src="./Components/MotorOutputReordering/MotorOutputReorderingCanvas.js"></script>
|
||||||
|
<script type="text/javascript" src="./Components/MotorOutputReordering/MotorOutputReorderingConfig.js"></script>
|
||||||
<title i18n="windowTitle"></title>
|
<title i18n="windowTitle"></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -99,8 +99,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="power_info">
|
<div class="power_info">
|
||||||
|
<a href="#" id="motorOutputReorderDialogOpen" class="regular-button" i18n="motorOutputReorderDialogOpen"></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>
|
||||||
|
@ -190,4 +190,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="clear-both"></div>
|
<div class="clear-both"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<dialog id="dialogMotorOutputReorder">
|
||||||
|
<div id="dialogMotorOutputReorderContentWrapper">
|
||||||
|
<div id="dialogMotorOutputReorderContent">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="#" id="dialogMotorOutputReorder-closebtn" class="regular-button right" i18n="motorOutputReorderDialogClose"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue