mirror of
https://github.com/iNavFlight/inav-configurator.git
synced 2025-07-22 15:55:28 +03:00
Merge branch 'master' of https://github.com/iNavFlight/inav-configurator into mission-planer
Fix conflicts: _locales/en/messages.json
This commit is contained in:
commit
db31180753
17 changed files with 466 additions and 128 deletions
|
@ -735,6 +735,15 @@
|
||||||
"configurationSPIProtocol": {
|
"configurationSPIProtocol": {
|
||||||
"message": "RX SPI protocol"
|
"message": "RX SPI protocol"
|
||||||
},
|
},
|
||||||
|
"configurationPersonalization": {
|
||||||
|
"message": "Personalization"
|
||||||
|
},
|
||||||
|
"configurationCraftName": {
|
||||||
|
"message": "Craft Name"
|
||||||
|
},
|
||||||
|
"configurationCraftNameHelp": {
|
||||||
|
"message": "Craft name. Can be displayed by OSD and by compatible RC systems."
|
||||||
|
},
|
||||||
"configurationEepromSaved": {
|
"configurationEepromSaved": {
|
||||||
"message": "EEPROM <span style=\"color: #37a8db\">saved</span>"
|
"message": "EEPROM <span style=\"color: #37a8db\">saved</span>"
|
||||||
},
|
},
|
||||||
|
@ -1130,10 +1139,6 @@
|
||||||
"transponderEepromSaved": {
|
"transponderEepromSaved": {
|
||||||
"message": "EEPROM <span style=\"color: #37a8db\">saved</span>"
|
"message": "EEPROM <span style=\"color: #37a8db\">saved</span>"
|
||||||
},
|
},
|
||||||
|
|
||||||
"servosFirmwareUpgradeRequired": {
|
|
||||||
"message": "Servos requires firmware >= 1.10.0. and target support."
|
|
||||||
},
|
|
||||||
"servosChangeDirection": {
|
"servosChangeDirection": {
|
||||||
"message": "Change Direction in TX To Match"
|
"message": "Change Direction in TX To Match"
|
||||||
},
|
},
|
||||||
|
@ -2320,6 +2325,7 @@
|
||||||
"downloadUpdatesBtn": {
|
"downloadUpdatesBtn": {
|
||||||
"message": "Download new app"
|
"message": "Download new app"
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"tabMissionControl": {
|
"tabMissionControl": {
|
||||||
"message": "Mission Control"
|
"message": "Mission Control"
|
||||||
},
|
},
|
||||||
|
@ -2358,5 +2364,14 @@
|
||||||
},
|
},
|
||||||
"confirm_delete_all_points": {
|
"confirm_delete_all_points": {
|
||||||
"message": "Do you really want to delete all points?"
|
"message": "Do you really want to delete all points?"
|
||||||
|
},
|
||||||
|
"servoMixer": {
|
||||||
|
"message": "Servo mixer"
|
||||||
|
},
|
||||||
|
"servoMixerDelete": {
|
||||||
|
"message": "Delete"
|
||||||
|
},
|
||||||
|
"servoMixerAdd": {
|
||||||
|
"message": "Add new mixer rule"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,8 @@ sources.js = [
|
||||||
'./js/localization.js',
|
'./js/localization.js',
|
||||||
'./js/boards.js',
|
'./js/boards.js',
|
||||||
'./js/tasks.js',
|
'./js/tasks.js',
|
||||||
|
'./js/servoMixRule.js',
|
||||||
|
'./js/servoMixRuleCollection.js',
|
||||||
'./main.js',
|
'./main.js',
|
||||||
'./tabs/*.js',
|
'./tabs/*.js',
|
||||||
'./js/eventFrequencyAnalyzer.js',
|
'./js/eventFrequencyAnalyzer.js',
|
||||||
|
|
24
js/fc.js
24
js/fc.js
|
@ -151,7 +151,7 @@ var FC = {
|
||||||
ADJUSTMENT_RANGES = [];
|
ADJUSTMENT_RANGES = [];
|
||||||
|
|
||||||
SERVO_CONFIG = [];
|
SERVO_CONFIG = [];
|
||||||
SERVO_RULES = [];
|
SERVO_RULES = new ServoMixRuleCollection();
|
||||||
|
|
||||||
SERIAL_CONFIG = {
|
SERIAL_CONFIG = {
|
||||||
ports: [],
|
ports: [],
|
||||||
|
@ -950,5 +950,27 @@ var FC = {
|
||||||
},
|
},
|
||||||
getRcMapLetters: function () {
|
getRcMapLetters: function () {
|
||||||
return ['A', 'E', 'R', 'T', '5', '6', '7', '8'];
|
return ['A', 'E', 'R', 'T', '5', '6', '7', '8'];
|
||||||
|
},
|
||||||
|
getServoMixInputNames: function () {
|
||||||
|
return [
|
||||||
|
'Stabilised Roll',
|
||||||
|
'Stabilised Pitch',
|
||||||
|
'Stabilised Yaw',
|
||||||
|
'Stabilised Throttle',
|
||||||
|
'RC Roll',
|
||||||
|
'RC Pitch',
|
||||||
|
'RC Yaw',
|
||||||
|
'RC Throttle',
|
||||||
|
'RC Channel 5',
|
||||||
|
'RC Channel 6',
|
||||||
|
'RC Channel 7',
|
||||||
|
'RC Channel 8',
|
||||||
|
'Gimbal Pitch',
|
||||||
|
'Gimbal Roll',
|
||||||
|
'Flaps'
|
||||||
|
];
|
||||||
|
},
|
||||||
|
getServoMixInputName: function (input) {
|
||||||
|
return getServoMixInputNames()[input];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
50
js/model.js
50
js/model.js
|
@ -2,29 +2,29 @@
|
||||||
|
|
||||||
// generate mixer
|
// generate mixer
|
||||||
var mixerList = [
|
var mixerList = [
|
||||||
{name: 'Tricopter', model: 'tricopter', image: 'tri'}, // 1
|
{name: 'Tricopter', model: 'tricopter', image: 'tri', hasCustomServoMixer: false}, // 1
|
||||||
{name: 'Quad +', model: 'quad_x', image: 'quad_p'}, // 2
|
{name: 'Quad +', model: 'quad_x', image: 'quad_p', hasCustomServoMixer: false}, // 2
|
||||||
{name: 'Quad X', model: 'quad_x', image: 'quad_x'}, // 3
|
{name: 'Quad X', model: 'quad_x', image: 'quad_x', hasCustomServoMixer: false}, // 3
|
||||||
{name: 'Bicopter', model: 'custom', image: 'bicopter'}, // 4
|
{name: 'Bicopter', model: 'custom', image: 'bicopter', hasCustomServoMixer: false}, // 4
|
||||||
{name: 'Gimbal', model: 'custom', image: 'custom'}, // 5
|
{name: 'Gimbal', model: 'custom', image: 'custom', hasCustomServoMixer: false}, // 5
|
||||||
{name: 'Y6', model: 'y6', image: 'y6'}, // 6
|
{name: 'Y6', model: 'y6', image: 'y6', hasCustomServoMixer: false}, // 6
|
||||||
{name: 'Hex +', model: 'hex_plus', image: 'hex_p'}, // 7
|
{name: 'Hex +', model: 'hex_plus', image: 'hex_p', hasCustomServoMixer: false}, // 7
|
||||||
{name: 'Flying Wing', model: 'custom', image: 'flying_wing'}, // 8
|
{name: 'Flying Wing', model: 'custom', image: 'flying_wing', hasCustomServoMixer: false}, // 8
|
||||||
{name: 'Y4', model: 'y4', image: 'y4'}, // 9
|
{name: 'Y4', model: 'y4', image: 'y4', hasCustomServoMixer: false}, // 9
|
||||||
{name: 'Hex X', model: 'hex_x', image: 'hex_x'}, // 10
|
{name: 'Hex X', model: 'hex_x', image: 'hex_x', hasCustomServoMixer: false}, // 10
|
||||||
{name: 'Octo X8', model: 'custom', image: 'octo_x8'}, // 11
|
{name: 'Octo X8', model: 'custom', image: 'octo_x8', hasCustomServoMixer: false}, // 11
|
||||||
{name: 'Octo Flat +', model: 'custom', image: 'octo_flat_p'}, // 12
|
{name: 'Octo Flat +', model: 'custom', image: 'octo_flat_p', hasCustomServoMixer: false}, // 12
|
||||||
{name: 'Octo Flat X', model: 'custom', image: 'octo_flat_x'}, // 13
|
{name: 'Octo Flat X', model: 'custom', image: 'octo_flat_x', hasCustomServoMixer: false}, // 13
|
||||||
{name: 'Airplane', model: 'custom', image: 'airplane'}, // 14
|
{name: 'Airplane', model: 'custom', image: 'airplane', hasCustomServoMixer: false}, // 14
|
||||||
{name: 'Heli 120', model: 'custom', image: 'custom'}, // 15
|
{name: 'Heli 120', model: 'custom', image: 'custom', hasCustomServoMixer: false}, // 15
|
||||||
{name: 'Heli 90', model: 'custom', image: 'custom'}, // 16
|
{name: 'Heli 90', model: 'custom', image: 'custom', hasCustomServoMixer: false}, // 16
|
||||||
{name: 'V-tail Quad', model: 'quad_vtail', image: 'vtail_quad'}, // 17
|
{name: 'V-tail Quad', model: 'quad_vtail', image: 'vtail_quad', hasCustomServoMixer: false}, // 17
|
||||||
{name: 'Hex H', model: 'custom', image: 'custom'}, // 18
|
{name: 'Hex H', model: 'custom', image: 'custom', hasCustomServoMixer: false}, // 18
|
||||||
{name: 'PPM to SERVO', model: 'custom', image: 'custom'}, // 19
|
{name: 'PPM to SERVO', model: 'custom', image: 'custom', hasCustomServoMixer: false}, // 19
|
||||||
{name: 'Dualcopter', model: 'custom', image: 'custom'}, // 20
|
{name: 'Dualcopter', model: 'custom', image: 'custom', hasCustomServoMixer: false}, // 20
|
||||||
{name: 'Singlecopter', model: 'custom', image: 'custom'}, // 21
|
{name: 'Singlecopter', model: 'custom', image: 'custom', hasCustomServoMixer: false}, // 21
|
||||||
{name: 'A-tail Quad', model: 'quad_atail', image: 'atail_quad'}, // 22
|
{name: 'A-tail Quad', model: 'quad_atail', image: 'atail_quad', hasCustomServoMixer: false}, // 22
|
||||||
{name: 'Custom', model: 'custom', image: 'custom'}, // 23
|
{name: 'Custom', model: 'custom', image: 'custom', hasCustomServoMixer: true}, // 23
|
||||||
{name: 'Custom Airplane', model: 'custom', image: 'custom'}, // 24
|
{name: 'Custom Airplane', model: 'custom', image: 'custom', hasCustomServoMixer: true}, // 24
|
||||||
{name: 'Custom Tricopter', model: 'custom', image: 'custom'} // 25
|
{name: 'Custom Tricopter', model: 'custom', image: 'custom', hasCustomServoMixer: true} // 25
|
||||||
];
|
];
|
||||||
|
|
|
@ -10,6 +10,9 @@ var MSPCodes = {
|
||||||
MSP_INAV_PID: 6,
|
MSP_INAV_PID: 6,
|
||||||
MSP_SET_INAV_PID: 7,
|
MSP_SET_INAV_PID: 7,
|
||||||
|
|
||||||
|
MSP_NAME: 10,
|
||||||
|
MSP_SET_NAME: 11,
|
||||||
|
|
||||||
MSP_NAV_POSHOLD: 12,
|
MSP_NAV_POSHOLD: 12,
|
||||||
MSP_SET_NAV_POSHOLD: 13,
|
MSP_SET_NAV_POSHOLD: 13,
|
||||||
MSP_CALIBRATION_DATA: 14,
|
MSP_CALIBRATION_DATA: 14,
|
||||||
|
|
|
@ -355,6 +355,20 @@ var mspHelper = (function (gui) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MSPCodes.MSP_SERVO_MIX_RULES:
|
case MSPCodes.MSP_SERVO_MIX_RULES:
|
||||||
|
SERVO_RULES.flush();
|
||||||
|
|
||||||
|
if (data.byteLength % 7 === 0) {
|
||||||
|
for (i = 0; i < data.byteLength; i += 7) {
|
||||||
|
SERVO_RULES.put(new ServoMixRule(
|
||||||
|
data.getInt8(i + 0, true),
|
||||||
|
data.getInt8(i + 1, true),
|
||||||
|
data.getInt8(i + 2, true),
|
||||||
|
data.getInt8(i + 3, true)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SERVO_RULES.cleanup();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSPCodes.MSP_SERVO_CONFIGURATIONS:
|
case MSPCodes.MSP_SERVO_CONFIGURATIONS:
|
||||||
|
@ -1106,6 +1120,11 @@ var mspHelper = (function (gui) {
|
||||||
case MSPCodes.MSP_OSD_CHAR_WRITE:
|
case MSPCodes.MSP_OSD_CHAR_WRITE:
|
||||||
console.log('OSD char uploaded');
|
console.log('OSD char uploaded');
|
||||||
break;
|
break;
|
||||||
|
case MSPCodes.MSP_NAME:
|
||||||
|
break;
|
||||||
|
case MSPCodes.MSP_SET_NAME:
|
||||||
|
console.log("Craft name set");
|
||||||
|
break;
|
||||||
case MSPCodes.MSPV2_SETTING:
|
case MSPCodes.MSPV2_SETTING:
|
||||||
break;
|
break;
|
||||||
case MSPCodes.MSPV2_SET_SETTING:
|
case MSPCodes.MSPV2_SET_SETTING:
|
||||||
|
@ -1693,7 +1712,6 @@ var mspHelper = (function (gui) {
|
||||||
nextFunction();
|
nextFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function send_next_servo_configuration() {
|
function send_next_servo_configuration() {
|
||||||
|
|
||||||
var buffer = [];
|
var buffer = [];
|
||||||
|
@ -1736,24 +1754,41 @@ var mspHelper = (function (gui) {
|
||||||
}
|
}
|
||||||
MSP.send_message(MSPCodes.MSP_SET_SERVO_CONFIGURATION, buffer, false, nextFunction);
|
MSP.send_message(MSPCodes.MSP_SET_SERVO_CONFIGURATION, buffer, false, nextFunction);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//FIXME looks like this is not used and not ever implemented
|
self.sendServoMixer = function (onCompleteCallback) {
|
||||||
//noinspection JSUnusedLocalSymbols
|
var nextFunction = sendMixer,
|
||||||
function send_channel_forwarding() {
|
servoIndex = 0;
|
||||||
|
|
||||||
|
if (SERVO_RULES.length == 0) {
|
||||||
|
onCompleteCallback();
|
||||||
|
} else {
|
||||||
|
nextFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendMixer() {
|
||||||
|
|
||||||
var buffer = [];
|
var buffer = [];
|
||||||
|
|
||||||
for (var i = 0; i < SERVO_CONFIG.length; i++) {
|
// send one at a time, with index
|
||||||
var out = SERVO_CONFIG[i].indexOfChannelToForward;
|
|
||||||
if (out == undefined) {
|
|
||||||
out = 255; // Cleanflight defines "CHANNEL_FORWARDING_DISABLED" as "(uint8_t)0xFF"
|
|
||||||
}
|
|
||||||
buffer.push(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var servoRule = SERVO_RULES.get()[servoIndex];
|
||||||
|
|
||||||
|
buffer.push(servoIndex);
|
||||||
|
buffer.push(servoRule.getTarget());
|
||||||
|
buffer.push(servoRule.getInput());
|
||||||
|
buffer.push(servoRule.getRate());
|
||||||
|
buffer.push(servoRule.getSpeed());
|
||||||
|
buffer.push(0);
|
||||||
|
buffer.push(0);
|
||||||
|
buffer.push(0);
|
||||||
|
|
||||||
|
// prepare for next iteration
|
||||||
|
servoIndex++;
|
||||||
|
if (servoIndex == 16) { //This is the last rule. Not pretty, but we have to send all rules
|
||||||
nextFunction = onCompleteCallback;
|
nextFunction = onCompleteCallback;
|
||||||
|
}
|
||||||
MSP.send_message(MSPCodes.MSP_SET_CHANNEL_FORWARDING, buffer, false, nextFunction);
|
MSP.send_message(MSPCodes.MSP_SET_SERVO_MIX_RULE, buffer, false, nextFunction);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2548,5 +2583,46 @@ var mspHelper = (function (gui) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.loadServoConfiguration = function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP_SERVO_CONFIGURATIONS, false, false, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.loadServoMixRules = function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP_SERVO_MIX_RULES, false, false, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.getCraftName = function(callback) {
|
||||||
|
if (semver.gt(CONFIG.flightControllerVersion, "1.8.0")) {
|
||||||
|
MSP.send_message(MSPCodes.MSP_NAME, false, false, function(resp) {
|
||||||
|
var name = "";
|
||||||
|
for (var ii = 0; ii < resp.data.byteLength; ii++) {
|
||||||
|
var c = resp.data.readU8();
|
||||||
|
if (c != 0) {
|
||||||
|
name += String.fromCharCode(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (callback) {
|
||||||
|
callback(name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (callback) {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.setCraftName = function(name, callback) {
|
||||||
|
if (semver.gt(CONFIG.flightControllerVersion, "1.8.0")) {
|
||||||
|
var data = [];
|
||||||
|
name = name || "";
|
||||||
|
for (var ii = 0; ii < name.length; ii++) {
|
||||||
|
data.push(name.charCodeAt(ii));
|
||||||
|
}
|
||||||
|
MSP.send_message(MSPCodes.MSP_SET_NAME, data, false, callback);
|
||||||
|
} else if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
})(GUI);
|
})(GUI);
|
||||||
|
|
|
@ -21,7 +21,7 @@ var MSPChainerClass = function () {
|
||||||
self.chainIndex++;
|
self.chainIndex++;
|
||||||
if (self.chain[self.chainIndex]) {
|
if (self.chain[self.chainIndex]) {
|
||||||
self.chain[self.chainIndex](self.returnCallback);
|
self.chain[self.chainIndex](self.returnCallback);
|
||||||
} else {
|
} else if (self.exitPoint) {
|
||||||
self.exitPoint();
|
self.exitPoint();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
45
js/servoMixRule.js
Normal file
45
js/servoMixRule.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*global $*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var ServoMixRule = function (target, input, rate, speed) {
|
||||||
|
|
||||||
|
var self = {};
|
||||||
|
|
||||||
|
self.getTarget = function () {
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.setTarget = function (data) {
|
||||||
|
target = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getInput = function () {
|
||||||
|
return input;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.setInput = function (data) {
|
||||||
|
input = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getRate = function () {
|
||||||
|
return rate;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.setRate = function (data) {
|
||||||
|
rate = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getSpeed = function () {
|
||||||
|
return speed;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.setSpeed = function (data) {
|
||||||
|
speed = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.isUsed = function () {
|
||||||
|
return rate !== 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
};
|
49
js/servoMixRuleCollection.js
Normal file
49
js/servoMixRuleCollection.js
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*global $, ServoMixRule*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var ServoMixRuleCollection = function () {
|
||||||
|
|
||||||
|
var self = {};
|
||||||
|
var data = [];
|
||||||
|
|
||||||
|
self.put = function (element) {
|
||||||
|
data.push(element);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.get = function () {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.drop = function (index) {
|
||||||
|
data[index].setRate(0);
|
||||||
|
self.cleanup();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.flush = function () {
|
||||||
|
data = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
self.cleanup = function () {
|
||||||
|
var tmpData = [];
|
||||||
|
|
||||||
|
data.forEach(function (element) {
|
||||||
|
if (element.isUsed()) {
|
||||||
|
tmpData.push(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
data = tmpData;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.inflate = function () {
|
||||||
|
while (self.hasFreeSlots()) {
|
||||||
|
self.put(new ServoMixRule(0, 0, 0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.hasFreeSlots = function () {
|
||||||
|
return data.length < 16;
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
};
|
9
main.css
9
main.css
|
@ -1326,6 +1326,15 @@ dialog {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.default_btn.narrow {
|
||||||
|
width: auto;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.default_btn.narrow a {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.default_btn a {
|
.default_btn a {
|
||||||
padding: 5px 0 5px 0;
|
padding: 5px 0 5px 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -20,9 +20,8 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-section .number input,
|
.config-section input,
|
||||||
.tab-configuration .number input {
|
.tab-configuration input {
|
||||||
width: 65px;
|
|
||||||
padding-left: 3px;
|
padding-left: 3px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
|
@ -34,8 +33,17 @@
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-configuration .number .disabled {
|
.config-section .number input,
|
||||||
|
.tab-configuration .number input {
|
||||||
width: 65px;
|
width: 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-section .string input,
|
||||||
|
.tab-configuration .string input {
|
||||||
|
width: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-configuration .disabled {
|
||||||
background-color: #ececec;
|
background-color: #ececec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +234,10 @@ hr {
|
||||||
left: 2em;
|
left: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.config-section .string label {
|
||||||
|
left: 175px;
|
||||||
|
}
|
||||||
|
|
||||||
.config-section .radio input {
|
.config-section .radio input {
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
|
|
|
@ -50,7 +50,16 @@
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-servos table tr:first-child {
|
#servo-mix-table input {
|
||||||
|
width: 75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#servo-mix-table .btn {
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#servo-config-table tr:first-child,
|
||||||
|
#servo-mix-table thead tr {
|
||||||
border-left: 1px solid #e4e4e4;
|
border-left: 1px solid #e4e4e4;
|
||||||
border-right: 1px solid #e4e4e4;
|
border-right: 1px solid #e4e4e4;
|
||||||
background-color: #828885;
|
background-color: #828885;
|
||||||
|
@ -154,22 +163,6 @@
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-servos .require-support {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-servos.supported .require-support {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-servos .require-upgrade {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-servos.supported .require-upgrade {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-servos .live span {
|
.tab-servos .live span {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,6 +212,21 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="config-section gui_box grey config-personalization">
|
||||||
|
<div class="gui_box_titlebar">
|
||||||
|
<div class="spacer_box_title" data-i18n="configurationPersonalization"></div>
|
||||||
|
</div>
|
||||||
|
<div class="spacer_box">
|
||||||
|
<div class="string">
|
||||||
|
<input maxlength="16" id="craft_name" name="craft_name" />
|
||||||
|
<label for="craft_name">
|
||||||
|
<span data-i18n="configurationCraftName"></span>
|
||||||
|
</label>
|
||||||
|
<div class="helpicon cf_tip" data-i18n_title="configurationCraftNameHelp"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Right column begins here-->
|
<!--Right column begins here-->
|
||||||
|
|
|
@ -10,6 +10,18 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
googleAnalytics.sendAppView('Configuration');
|
googleAnalytics.sendAppView('Configuration');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var craftName = null;
|
||||||
|
var loadCraftName = function(callback) {
|
||||||
|
mspHelper.getCraftName(function(name) {
|
||||||
|
craftName = name;
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var saveCraftName = function(callback) {
|
||||||
|
mspHelper.setCraftName(craftName, callback);
|
||||||
|
};
|
||||||
|
|
||||||
var loadChainer = new MSPChainerClass();
|
var loadChainer = new MSPChainerClass();
|
||||||
|
|
||||||
loadChainer.setChain([
|
loadChainer.setChain([
|
||||||
|
@ -22,7 +34,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
mspHelper.loadSensorAlignment,
|
mspHelper.loadSensorAlignment,
|
||||||
mspHelper.loadAdvancedConfig,
|
mspHelper.loadAdvancedConfig,
|
||||||
mspHelper.loadINAVPidConfig,
|
mspHelper.loadINAVPidConfig,
|
||||||
mspHelper.loadSensorConfig
|
mspHelper.loadSensorConfig,
|
||||||
|
loadCraftName
|
||||||
]);
|
]);
|
||||||
loadChainer.setExitPoint(load_html);
|
loadChainer.setExitPoint(load_html);
|
||||||
loadChainer.execute();
|
loadChainer.execute();
|
||||||
|
@ -41,6 +54,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
mspHelper.saveAdvancedConfig,
|
mspHelper.saveAdvancedConfig,
|
||||||
mspHelper.saveINAVPidConfig,
|
mspHelper.saveINAVPidConfig,
|
||||||
mspHelper.saveSensorConfig,
|
mspHelper.saveSensorConfig,
|
||||||
|
saveCraftName,
|
||||||
mspHelper.saveToEeprom
|
mspHelper.saveToEeprom
|
||||||
]);
|
]);
|
||||||
saveChainer.setExitPoint(reboot);
|
saveChainer.setExitPoint(reboot);
|
||||||
|
@ -597,6 +611,14 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Craft name
|
||||||
|
if (craftName != null) {
|
||||||
|
$('.config-personalization').show();
|
||||||
|
$('input[name="craft_name"]').val(craftName);
|
||||||
|
} else {
|
||||||
|
// craft name not supported by the firmware
|
||||||
|
$('.config-personalization').hide();
|
||||||
|
}
|
||||||
|
|
||||||
$('a.save').click(function () {
|
$('a.save').click(function () {
|
||||||
// gather data that doesn't have automatic change event bound
|
// gather data that doesn't have automatic change event bound
|
||||||
|
@ -635,6 +657,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
SENSOR_ALIGNMENT.align_acc = parseInt(orientation_acc_e.val());
|
SENSOR_ALIGNMENT.align_acc = parseInt(orientation_acc_e.val());
|
||||||
SENSOR_ALIGNMENT.align_mag = parseInt(orientation_mag_e.val());
|
SENSOR_ALIGNMENT.align_mag = parseInt(orientation_mag_e.val());
|
||||||
|
|
||||||
|
craftName = $('input[name="craft_name"]').val();
|
||||||
|
|
||||||
var rxTypes = FC.getRxTypes();
|
var rxTypes = FC.getRxTypes();
|
||||||
|
|
||||||
function is_using_rx_type(name) {
|
function is_using_rx_type(name) {
|
||||||
|
|
|
@ -421,7 +421,7 @@ OSD.constants = {
|
||||||
{
|
{
|
||||||
name: 'FLYMODE',
|
name: 'FLYMODE',
|
||||||
id: 7,
|
id: 7,
|
||||||
preview: 'STAB'
|
preview: 'ACRO'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'MESSAGES',
|
name: 'MESSAGES',
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
<!--suppress HtmlFormInputWithoutLabel -->
|
|
||||||
<div class="tab-servos toolbar_fixed_bottom">
|
<div class="tab-servos toolbar_fixed_bottom">
|
||||||
<div class="content_wrapper">
|
<div class="content_wrapper">
|
||||||
<div class="tab_title" data-i18n="tabServos">Servos</div>
|
<div class="tab_title" data-i18n="tabServos">Servos</div>
|
||||||
<div class="cf_doc_version_bt">
|
<div class="cf_doc_version_bt">
|
||||||
<a id="button-documentation" href="" target="_blank"></a>
|
<a id="button-documentation" href="" target="_blank"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="require-support">
|
<div>
|
||||||
<div class="title" data-i18n="servosChangeDirection"></div>
|
<div class="title" data-i18n="servosChangeDirection"></div>
|
||||||
<table class="fields">
|
<table id="servo-config-table" class="fields">
|
||||||
<tr class="main">
|
<tr class="main">
|
||||||
<th width="110px" data-i18n="servosName"></th>
|
<th width="110px" data-i18n="servosName"></th>
|
||||||
<th data-i18n="servosMid"></th>
|
<th data-i18n="servosMid"></th>
|
||||||
|
@ -23,9 +22,28 @@
|
||||||
<input type="checkbox" class="togglemedium" /> <span data-i18n="servosLiveMode"></span>
|
<input type="checkbox" class="togglemedium" /> <span data-i18n="servosLiveMode"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="note require-upgrade">
|
<div class="clear-both"></div>
|
||||||
<div class="note_spacer">
|
<div id="servo-mix-table-wrapper" class="margin-top">
|
||||||
<p data-i18n="servosFirmwareUpgradeRequired"></p>
|
<div class="tab_title" data-i18n="servoMixer">Servo mixer</div>
|
||||||
|
<div class="btn default_btn narrow pull-right" style="margin-bottom: 15px">
|
||||||
|
<a href="#" data-role="role-add" data-i18n="servoMixerAdd"></a>
|
||||||
|
</div>
|
||||||
|
<table id="servo-mix-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 75px">Servo</th>
|
||||||
|
<th>Input</th>
|
||||||
|
<th>Weight</th>
|
||||||
|
<th>Speed</th>
|
||||||
|
<th style="width: 75px"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="btn default_btn narrow pull-right" style="margin-bottom: 15px">
|
||||||
|
<a href="#" data-role="role-add" data-i18n="servoMixerAdd"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
149
tabs/servos.js
149
tabs/servos.js
|
@ -9,40 +9,98 @@ TABS.servos.initialize = function (callback) {
|
||||||
googleAnalytics.sendAppView('Servos');
|
googleAnalytics.sendAppView('Servos');
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_servo_configurations() {
|
var loadChainer = new MSPChainerClass();
|
||||||
MSP.send_message(MSPCodes.MSP_SERVO_CONFIGURATIONS, false, false, get_servo_mix_rules);
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_servo_mix_rules() {
|
loadChainer.setChain([
|
||||||
MSP.send_message(MSPCodes.MSP_SERVO_MIX_RULES, false, false, get_rc_data);
|
mspHelper.loadServoConfiguration,
|
||||||
}
|
mspHelper.loadRcData,
|
||||||
|
mspHelper.loadBfConfig,
|
||||||
|
mspHelper.loadServoMixRules
|
||||||
|
]);
|
||||||
|
loadChainer.setExitPoint(load_html);
|
||||||
|
loadChainer.execute();
|
||||||
|
|
||||||
function get_rc_data() {
|
var saveChainer = new MSPChainerClass();
|
||||||
MSP.send_message(MSPCodes.MSP_RC, false, false, get_boxnames_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_boxnames_data() {
|
saveChainer.setChain([
|
||||||
MSP.send_message(MSPCodes.MSP_BOXNAMES, false, false, load_html);
|
mspHelper.sendServoConfigurations,
|
||||||
}
|
mspHelper.sendServoMixer,
|
||||||
|
mspHelper.saveToEeprom
|
||||||
|
]);
|
||||||
|
saveChainer.setExitPoint(function () {
|
||||||
|
GUI.log(chrome.i18n.getMessage('servosEepromSave'));
|
||||||
|
SERVO_RULES.cleanup();
|
||||||
|
renderServoMixRules();
|
||||||
|
});
|
||||||
|
|
||||||
function load_html() {
|
function load_html() {
|
||||||
$('#content').load("./tabs/servos.html", process_html);
|
$('#content').load("./tabs/servos.html", process_html);
|
||||||
}
|
}
|
||||||
|
|
||||||
get_servo_configurations();
|
function renderServoMixRules() {
|
||||||
|
|
||||||
|
var $servoMixTable = $('#servo-mix-table'),
|
||||||
|
$servoMixTableBody = $servoMixTable.find('tbody');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process servo mix table UI
|
||||||
|
*/
|
||||||
|
var rules = SERVO_RULES.get();
|
||||||
|
$servoMixTableBody.find("*").remove();
|
||||||
|
for (servoRuleIndex in rules) {
|
||||||
|
if (rules.hasOwnProperty(servoRuleIndex)) {
|
||||||
|
const servoRule = rules[servoRuleIndex];
|
||||||
|
|
||||||
|
$servoMixTableBody.append('\
|
||||||
|
<tr>\
|
||||||
|
<td><input type="number" class="mix-rule-servo" step="1" min="0" max="7" /></td>\
|
||||||
|
<td><select class="mix-rule-input"></select></td>\
|
||||||
|
<td><input type="number" class="mix-rule-rate" step="1" min="-100" max="100" /></td>\
|
||||||
|
<td><input type="number" class="mix-rule-speed" step="1" min="0" max="255" /></td>\
|
||||||
|
<td><span class="btn default_btn narrow"><a href="#" data-role="role-delete" data-i18n="servoMixerDelete"></a></span></td>\
|
||||||
|
</tr>\
|
||||||
|
');
|
||||||
|
|
||||||
|
const $row = $servoMixTableBody.find('tr:last');
|
||||||
|
|
||||||
|
GUI.fillSelect($row.find(".mix-rule-input"), FC.getServoMixInputNames(), servoRule.getInput());
|
||||||
|
|
||||||
|
$row.find(".mix-rule-input").val(servoRule.getInput()).change(function () {
|
||||||
|
servoRule.setInput($(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
$row.find(".mix-rule-servo").val(servoRule.getTarget()).change(function () {
|
||||||
|
servoRule.setTarget($(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
$row.find(".mix-rule-rate").val(servoRule.getRate()).change(function () {
|
||||||
|
servoRule.setRate($(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
$row.find(".mix-rule-speed").val(servoRule.getSpeed()).change(function () {
|
||||||
|
servoRule.setSpeed($(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
$row.find("[data-role='role-delete']").attr("data-index", servoRuleIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
localize();
|
||||||
|
}
|
||||||
|
|
||||||
function update_ui() {
|
function update_ui() {
|
||||||
|
|
||||||
var i,
|
var i,
|
||||||
$tabServos = $(".tab-servos");
|
$tabServos = $(".tab-servos"),
|
||||||
|
$servoConfigTable = $('#servo-config-table'),
|
||||||
|
$servoMixTable = $('#servo-mix-table'),
|
||||||
|
$servoMixTableBody = $servoMixTable.find('tbody');
|
||||||
|
|
||||||
if (SERVO_CONFIG.length == 0) {
|
if (SERVO_CONFIG.length == 0) {
|
||||||
$tabServos.removeClass("supported");
|
$tabServos.addClass("is-hidden");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tabServos.addClass("supported");
|
|
||||||
|
|
||||||
var servoCheckbox = '';
|
var servoCheckbox = '';
|
||||||
var servoHeader = '';
|
var servoHeader = '';
|
||||||
for (i = 0; i < RC.active_channels - 4; i++) {
|
for (i = 0; i < RC.active_channels - 4; i++) {
|
||||||
|
@ -54,13 +112,11 @@ TABS.servos.initialize = function (callback) {
|
||||||
servoCheckbox = servoCheckbox + '<td class="channel"><input type="checkbox"/></td>';
|
servoCheckbox = servoCheckbox + '<td class="channel"><input type="checkbox"/></td>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$('div.tab-servos table.fields tr.main').append(servoHeader);
|
$servoConfigTable.find('tr.main').append(servoHeader);
|
||||||
|
|
||||||
function process_servos(name, alternate, obj) {
|
function process_servos(name, alternate, obj) {
|
||||||
|
|
||||||
$('div.supported_wrapper').show();
|
$servoConfigTable.append('\
|
||||||
|
|
||||||
$('div.tab-servos table.fields').append('\
|
|
||||||
<tr> \
|
<tr> \
|
||||||
<td style="text-align: center">' + name + '</td>\
|
<td style="text-align: center">' + name + '</td>\
|
||||||
<td class="middle"><input type="number" min="500" max="2500" value="' + SERVO_CONFIG[obj].middle + '" /></td>\
|
<td class="middle"><input type="number" min="500" max="2500" value="' + SERVO_CONFIG[obj].middle + '" /></td>\
|
||||||
|
@ -73,13 +129,13 @@ TABS.servos.initialize = function (callback) {
|
||||||
');
|
');
|
||||||
|
|
||||||
if (SERVO_CONFIG[obj].indexOfChannelToForward >= 0) {
|
if (SERVO_CONFIG[obj].indexOfChannelToForward >= 0) {
|
||||||
$('div.tab-servos table.fields tr:last td.channel input').eq(SERVO_CONFIG[obj].indexOfChannelToForward).prop('checked', true);
|
$servoConfigTable.find('tr:last td.channel input').eq(SERVO_CONFIG[obj].indexOfChannelToForward).prop('checked', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// adding select box and generating options
|
// adding select box and generating options
|
||||||
$('div.tab-servos table.fields tr:last td.direction').append('<select class="rate" name="rate"></select>');
|
$servoConfigTable.find('tr:last td.direction').append('<select class="rate" name="rate"></select>');
|
||||||
|
|
||||||
var select = $('div.tab-servos table.fields tr:last td.direction select');
|
var select = $servoConfigTable.find('tr:last td.direction select');
|
||||||
|
|
||||||
for (var i = FC.MAX_SERVO_RATE; i >= FC.MIN_SERVO_RATE; i--) {
|
for (var i = FC.MAX_SERVO_RATE; i >= FC.MIN_SERVO_RATE; i--) {
|
||||||
select.append('<option value="' + i + '">Rate: ' + i + '%</option>');
|
select.append('<option value="' + i + '">Rate: ' + i + '%</option>');
|
||||||
|
@ -88,12 +144,12 @@ TABS.servos.initialize = function (callback) {
|
||||||
// select current rate
|
// select current rate
|
||||||
select.val(SERVO_CONFIG[obj].rate);
|
select.val(SERVO_CONFIG[obj].rate);
|
||||||
|
|
||||||
$('div.tab-servos table.fields tr:last').data('info', {'obj': obj});
|
$servoConfigTable.find('tr:last').data('info', { 'obj': obj });
|
||||||
|
|
||||||
// UI hooks
|
// UI hooks
|
||||||
|
|
||||||
// only one checkbox for indicating a channel to forward can be selected at a time, perhaps a radio group would be best here.
|
// only one checkbox for indicating a channel to forward can be selected at a time, perhaps a radio group would be best here.
|
||||||
$('div.tab-servos table.fields tr:last td.channel input').click(function () {
|
$servoConfigTable.find('tr:last td.channel input').click(function () {
|
||||||
if ($(this).is(':checked')) {
|
if ($(this).is(':checked')) {
|
||||||
$(this).parent().parent().find('.channel input').not($(this)).prop('checked', false);
|
$(this).parent().parent().find('.channel input').not($(this)).prop('checked', false);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +157,7 @@ TABS.servos.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function servos_update(save_configuration_to_eeprom) {
|
function servos_update(save_configuration_to_eeprom) {
|
||||||
$('div.tab-servos table.fields tr:not(".main")').each(function () {
|
$servoConfigTable.find('tr:not(".main")').each(function () {
|
||||||
var info = $(this).data('info');
|
var info = $(this).data('info');
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,42 +169,28 @@ TABS.servos.initialize = function (callback) {
|
||||||
|
|
||||||
SERVO_CONFIG[info.obj].indexOfChannelToForward = channelIndex;
|
SERVO_CONFIG[info.obj].indexOfChannelToForward = channelIndex;
|
||||||
|
|
||||||
|
|
||||||
SERVO_CONFIG[info.obj].middle = parseInt($('.middle input', this).val());
|
SERVO_CONFIG[info.obj].middle = parseInt($('.middle input', this).val());
|
||||||
SERVO_CONFIG[info.obj].min = parseInt($('.min input', this).val());
|
SERVO_CONFIG[info.obj].min = parseInt($('.min input', this).val());
|
||||||
SERVO_CONFIG[info.obj].max = parseInt($('.max input', this).val());
|
SERVO_CONFIG[info.obj].max = parseInt($('.max input', this).val());
|
||||||
SERVO_CONFIG[info.obj].rate = parseInt($('.direction select', this).val());
|
SERVO_CONFIG[info.obj].rate = parseInt($('.direction select', this).val());
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//Save configuration to FC
|
||||||
// send data to FC
|
SERVO_RULES.cleanup();
|
||||||
//
|
SERVO_RULES.inflate();
|
||||||
//FIXME investigate why the same frame is sent twice
|
saveChainer.execute();
|
||||||
mspHelper.sendServoConfigurations(send_servo_mixer_rules);
|
|
||||||
|
|
||||||
function send_servo_mixer_rules() {
|
|
||||||
mspHelper.sendServoConfigurations(save_to_eeprom);
|
|
||||||
}
|
|
||||||
|
|
||||||
function save_to_eeprom() {
|
|
||||||
if (save_configuration_to_eeprom) {
|
|
||||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, function () {
|
|
||||||
GUI.log(chrome.i18n.getMessage('servosEepromSave'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop previous table
|
// drop previous table
|
||||||
$('div.tab-servos table.fields tr:not(:first)').remove();
|
$servoConfigTable.find('tr:not(:first)').remove();
|
||||||
|
|
||||||
for (var servoIndex = 0; servoIndex < 8; servoIndex++) {
|
for (var servoIndex = 0; servoIndex < 8; servoIndex++) {
|
||||||
process_servos('Servo ' + servoIndex, '', servoIndex, false);
|
process_servos('Servo ' + servoIndex, '', servoIndex, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI hooks for dynamically generated elements
|
// UI hooks for dynamically generated elements
|
||||||
$('table.directions select, table.directions input, table.fields select, table.fields input').change(function () {
|
$('table.directions select, table.directions input, #servo-config-table select, #servo-config-table input').change(function () {
|
||||||
if ($('div.live input').is(':checked')) {
|
if ($('div.live input').is(':checked')) {
|
||||||
// apply small delay as there seems to be some funky update business going wrong
|
// apply small delay as there seems to be some funky update business going wrong
|
||||||
helper.timeout.add('servos_update', servos_update, 10);
|
helper.timeout.add('servos_update', servos_update, 10);
|
||||||
|
@ -159,6 +201,19 @@ TABS.servos.initialize = function (callback) {
|
||||||
servos_update(true);
|
servos_update(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$servoMixTableBody.on('click', "[data-role='role-delete']", function (event) {
|
||||||
|
SERVO_RULES.drop($(event.currentTarget).attr("data-index"));
|
||||||
|
renderServoMixRules();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("[data-role='role-add']").click(function () {
|
||||||
|
if (SERVO_RULES.hasFreeSlots()) {
|
||||||
|
SERVO_RULES.put(new ServoMixRule(0, 0, 0, 0));
|
||||||
|
renderServoMixRules();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
renderServoMixRules();
|
||||||
}
|
}
|
||||||
|
|
||||||
function process_html() {
|
function process_html() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue