1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-23 16:25:22 +03:00

Merge remote-tracking branch 'upstream/master' into feature-replace-logo

This commit is contained in:
Kiripolszky Károly 2018-04-04 22:01:47 +02:00
commit 365b05987f
47 changed files with 19829 additions and 3968 deletions

View file

@ -27,7 +27,7 @@ Download the installer from [Releases.](https://github.com/betaflight/betaflight
[![available in the Chrome web store](https://developer.chrome.com/webstore/images/ChromeWebStore_Badge_v2_206x58.png)](https://chrome.google.com/webstore/detail/betaflight-configurator/kdaghagfopacdngbohiknlhcocjccjao) [![available in the Chrome web store](https://developer.chrome.com/webstore/images/ChromeWebStore_Badge_v2_206x58.png)](https://chrome.google.com/webstore/detail/betaflight-configurator/kdaghagfopacdngbohiknlhcocjccjao)
1. Visit [Chrome web store](https://chrome.google.com/webstore/detail/betaflight-configurator/kdaghagfopacdngbohiknlhcocjccjao) 1. Visit the [Betaflight Configurator product page in the Chrome web store](https://chrome.google.com/webstore/detail/betaflight-configurator/kdaghagfopacdngbohiknlhcocjccjao)
2. Click **+ Add to Chrome** 2. Click **+ Add to Chrome**
Please note - the application will automatically update itself when new versions are released. Please ensure you maintain configuration backups as described in the Betaflight documentation. Please note - the application will automatically update itself when new versions are released. Please ensure you maintain configuration backups as described in the Betaflight documentation.
@ -85,9 +85,9 @@ You can also use multiple platforms e.g. `gulp <taskname> --osx64 --linux64`.
## Languages ## Languages
Betaflight Configurator has been translated to several languages. The application will be shown in your system language if a translation into this language is available. You can help [translating the application into your language](http://betaflight.oneskyapp.com). Betaflight Configurator has been translated into several languages. The application will try to detect and use your system language if a translation into this language is available. You can help [translating the application into your language](https://crowdin.com/project/betaflight-configurator).
If you prefer to have the application in english, you can execute the program from the command line adding a parameter `--lang=en` (for Windows systems) or adding a `LANGUAGE=en` before the name of the program (for Linux systems, for example `LANGUAGE=en ./betaflight-configurator`). You can create a script or a shortcut with this parameter included. If you prefer to have the application in English or any other language, you can select your desired language in the options menu of the application.
## Notes ## Notes
@ -130,3 +130,5 @@ We accept clean and reasonable patches, submit them!
ctn - primary author and maintainer of Baseflight Configurator from which Cleanflight Configurator project was forked. ctn - primary author and maintainer of Baseflight Configurator from which Cleanflight Configurator project was forked.
Hydra - author and maintainer of Cleanflight Configurator from which this project was forked. Hydra - author and maintainer of Cleanflight Configurator from which this project was forked.
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/betaflight-configurator/localized.svg)](https://crowdin.com/project/betaflight-configurator)

View file

@ -5,3 +5,4 @@ Exec=/opt/betaflight/betaflight-configurator/betaflight-configurator
Icon=/opt/betaflight/betaflight-configurator/icon/bf_icon_128.png Icon=/opt/betaflight/betaflight-configurator/icon/bf_icon_128.png
Terminal=false Terminal=false
Type=Application Type=Application
Categories=Utility

View file

@ -1,4 +1,23 @@
This package was created by the Betaflight open source flight controller firmware project (https://github.com/betaflight/betaflight). Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Betaflight Configurator
Source: https://github.com/betaflight/betaflight-configurator
All of the code is covered under the terms of the GPL version 3. See the Files: *
file /usr/share/common-licenses/GPL-3 for more information. Copyright: Copyright 2018 The Betaflight open source project
License: GPL-3
License: GPL-3
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
.
On Debian systems, the complete text of the GNU General Public License
can be found in `/usr/share/common-licenses/GPL-3'.

View file

@ -49,7 +49,11 @@ OutFile "..\..\${DEST_FOLDER}\${FILE_NAME_INSTALLER}"
!insertmacro MUI_LANGUAGE "Catalan" !insertmacro MUI_LANGUAGE "Catalan"
!insertmacro MUI_LANGUAGE "French" !insertmacro MUI_LANGUAGE "French"
!insertmacro MUI_LANGUAGE "German" !insertmacro MUI_LANGUAGE "German"
!insertmacro MUI_LANGUAGE "Italian"
!insertmacro MUI_LANGUAGE "Japanese"
!insertmacro MUI_LANGUAGE "Korean" !insertmacro MUI_LANGUAGE "Korean"
!insertmacro MUI_LANGUAGE "Latvian"
!insertmacro MUI_LANGUAGE "Portuguese"
!insertmacro MUI_LANGUAGE "SimpChinese" !insertmacro MUI_LANGUAGE "SimpChinese"
!insertmacro MUI_LANGUAGE "Spanish" !insertmacro MUI_LANGUAGE "Spanish"

32
crowdin.yml Normal file
View file

@ -0,0 +1,32 @@
#
# Files configuration
#
"preserve_hierarchy": false
files: [
{
#
# Source files filter
# e.g. "/resources/en/*.json"
#
"source" : "/locales/en/messages.json",
#
# where translations live
# e.g. "/resources/%two_letters_code%/%original_file_name%"
#
"translation" : "/locales/%two_letters_code%/%original_file_name%",
#
# Often software projects have custom names for locale directories. crowdin-cli allows you to map your own languages to be understandable by Crowdin.
#
"languages_mapping" : {
"two_letters_code" : {
"es-ES" : "es",
"pt-PT" : "pt",
"sv-SE" : "sv",
"zh-CN" : "zh_CN"
}
}
}
]

View file

@ -26,7 +26,7 @@ const DEBUG_DIR = './debug/';
const RELEASE_DIR = './release/'; const RELEASE_DIR = './release/';
var nwBuilderOptions = { var nwBuilderOptions = {
version: '0.27.4', version: '0.28.3',
files: './dist/**/*', files: './dist/**/*',
macIcns: './src/images/bf_icon.icns', macIcns: './src/images/bf_icon.icns',
macPlist: { 'CFBundleDisplayName': 'Betaflight Configurator'}, macPlist: { 'CFBundleDisplayName': 'Betaflight Configurator'},

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -69,31 +69,75 @@
"language_fr": { "language_fr": {
"message": "Fran\u00e7ais (fr)" "message": "Fran\u00e7ais (fr)"
}, },
"language_it": {
"message": "Italiano (it)"
},
"language_ja": {
"message": "\u65E5\u672C\u8A9E (ja)"
},
"language_ko": { "language_ko": {
"message": "\ud55c\uad6d\uc5b4 (ko)" "message": "\ud55c\uad6d\uc5b4 (ko)"
}, },
"language_lv": {
"message": "Latvie\u0161u (lv)"
},
"language_pt": {
"message": "Portugu\u00EAs (pt)"
},
"language_zh_CN": { "language_zh_CN": {
"message": "\u7b80\u4f53\u4e2d\u6587 (zh_CN)" "message": "\u7b80\u4f53\u4e2d\u6587 (zh_CN)"
}, },
"sensorDataFlashNotFound": {
"message": "No dataflash <br>chip found",
"description": "Text of the dataflash image in the header of the page."
},
"sensorDataFlashFreeSpace": {
"message": "Dataflash: free space",
"description": "Text of the dataflash image in the header of the page."
},
"sensorStatusGyro": { "sensorStatusGyro": {
"message": "Gyroscope" "message": "Gyroscope"
}, },
"sensorStatusGyroShort": {
"message": "Gyro",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusAccel": { "sensorStatusAccel": {
"message": "Accelerometer" "message": "Accelerometer"
}, },
"sensorStatusAccelShort": {
"message": "Accel",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusMag": { "sensorStatusMag": {
"message": "Magnetometer" "message": "Magnetometer"
}, },
"sensorStatusMagShort": {
"message": "Mag",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusBaro": { "sensorStatusBaro": {
"message": "Barometer" "message": "Barometer"
}, },
"sensorStatusBaroShort": {
"message": "Baro",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusGPS": { "sensorStatusGPS": {
"message": "GPS" "message": "GPS"
}, },
"sensorStatusGPSShort": {
"message": "GPS",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusSonar": { "sensorStatusSonar": {
"message": "Sonar / Range finder" "message": "Sonar / Range finder"
}, },
"sensorStatusSonarShort": {
"message": "Sonar",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"checkForConfiguratorUnstableVersions": { "checkForConfiguratorUnstableVersions": {
"message": "Show update notifications for unstable versions of the configurator" "message": "Show update notifications for unstable versions of the configurator"
}, },
@ -327,7 +371,8 @@
}, },
"infoVersions": { "infoVersions": {
"message" : "Running - OS: <strong>$1</strong>, Chrome: <strong>$2</strong>, Configurator: <strong>$3</strong>" "message" : "Running - OS: <strong>{{operatingSystem}}</strong>, Chrome: <strong>{{chromeVersion}}</strong>, Configurator: <strong>{{configuratorVersion}}</strong>",
"description": "Message that appears in the GUI log panel indicating operating system, Chrome version and Configurator version"
}, },
"releaseCheckLoaded": { "releaseCheckLoaded": {
"message" : "Loaded release information for $1 from GitHub." "message" : "Loaded release information for $1 from GitHub."
@ -369,6 +414,12 @@
"armingEnabled": { "armingEnabled": {
"message": "<strong>Arming Enabled</strong>" "message": "<strong>Arming Enabled</strong>"
}, },
"runawayTakeoffPreventionDisabled": {
"message": "<strong>Runaway Takeoff Prevention temporarily Disabled</strong>"
},
"runawayTakeoffPreventionEnabled": {
"message": "<strong>Runaway Takeoff Prevention Enabled</strong>"
},
"boardInfoReceived": { "boardInfoReceived": {
"message": "Board: <strong>$1</strong>, version: <strong>$2</strong>" "message": "Board: <strong>$1</strong>, version: <strong>$2</strong>"
}, },
@ -424,10 +475,10 @@
"message": "Erased $1 kB of flash <span class=\"message-positive\">successfully</span>" "message": "Erased $1 kB of flash <span class=\"message-positive\">successfully</span>"
}, },
"dfu_device_flash_info": { "dfu_device_flash_info": {
"message": "Detected device with total flash size $1 kiB" "message": "Detected device with total flash size $1 KiB"
}, },
"dfu_error_image_size": { "dfu_error_image_size": {
"message": "<span class=\"message-negative\">Error</span>: Supplied image is larger then flash available on the chip! Image: $1 kiB, limit = $2 kiB" "message": "<span class=\"message-negative\">Error</span>: Supplied image is larger then flash available on the chip! Image: $1 KiB, limit = $2 KiB"
}, },
"eeprom_saved_ok": { "eeprom_saved_ok": {
@ -448,7 +499,7 @@
"message": "Contributing" "message": "Contributing"
}, },
"defaultContributingText": { "defaultContributingText": {
"message": "If you would like to help make Betaflight even better you can help in many ways, including:<br /><ul><li>Answering other users questions on the forums and IRC.</li><li>Contributing code to the firmware and configurator - new features, fixes, improvements</li><li>Testing <a href=\"https://github.com/Betaflight/betaflight/pulls\" target=\"_blank\">new features/fixes</a> and providing feedback.</li><li>Helping out with <a href=\"https://github.com/betaflight/betaflight/issues\" target=\"_blank\">issues and commenting on feature requests</a>.</li><li>Collaborate by <a href=\"http://betaflight.oneskyapp.com\" target=\"_blank\">translating the configurator application</a> into your language.</li><li></li></ul>" "message": "If you would like to help make Betaflight even better you can help in many ways, including:<br /><ul><li>Answering other users questions on the forums and IRC.</li><li>Contributing code to the firmware and configurator - new features, fixes, improvements</li><li>Testing <a href=\"https://github.com/Betaflight/betaflight/pulls\" target=\"_blank\">new features/fixes</a> and providing feedback.</li><li>Helping out with <a href=\"https://github.com/betaflight/betaflight/issues\" target=\"_blank\">issues and commenting on feature requests</a>.</li><li>Collaborate by <a href=\"https://crowdin.com/project/betaflight-configurator\" target=\"_blank\">translating the configurator application</a> into your language.</li><li></li></ul>"
}, },
"defaultChangelogAction": { "defaultChangelogAction": {
"message": "Changelog" "message": "Changelog"
@ -913,6 +964,15 @@
"configurationThrottleMinimumCommandHelp": { "configurationThrottleMinimumCommandHelp": {
"message": "This is the value that is sent to the ESCs when the craft is disarmed. Set this to a value that has the motors stopped (1000 for most ESCs)." "message": "This is the value that is sent to the ESCs when the craft is disarmed. Set this to a value that has the motors stopped (1000 for most ESCs)."
}, },
"configurationDshotBeeper": {
"message": "DSHOT Beacon Configuration"
},
"configurationUseDshotBeeper": {
"message": "Use DSHOT beacon (use motors to sound beeps when disarmed)"
},
"configurationDshotBeaconTone": {
"message": "Beacon Tone"
},
"configurationBeeper": { "configurationBeeper": {
"message": "Beeper Configuration" "message": "Beeper Configuration"
}, },
@ -1121,13 +1181,15 @@
"portsFunction_RUNCAM_DEVICE_CONTROL": { "portsFunction_RUNCAM_DEVICE_CONTROL": {
"message": "RunCam Device" "message": "RunCam Device"
}, },
"pidTuningProfileOption": { "pidTuningProfileOption": {
"message": "Profile $1" "message": "Profile $1"
}, },
"pidTuningRateProfileOption": { "pidTuningRateProfileOption": {
"message": "Rateprofile $1" "message": "Rateprofile $1"
}, },
"portsFunction_LIDAR_TF": {
"message": "Benewake LIDAR"
},
"pidTuningUpgradeFirmwareToChangePidController": { "pidTuningUpgradeFirmwareToChangePidController": {
"message": "<span class=\"message-negative\">Changing PID controller disabled - you can change it via the CLI.</span> You have firmware with API version <span class=\"message-negative\">$1</span>, but this functionality requires <span class=\"message-positive\">$2</span>." "message": "<span class=\"message-negative\">Changing PID controller disabled - you can change it via the CLI.</span> You have firmware with API version <span class=\"message-negative\">$1</span>, but this functionality requires <span class=\"message-positive\">$2</span>."
}, },
@ -1303,7 +1365,7 @@
"message": "Please read receiver chapter of the documentation. Configure serial port (if required), receiver mode (serial/ppm/pwm), provider (for serial receivers), bind receiver, set channel map, configure channel endpoints/range on TX so that all channels go from ~1000 to ~2000. Set midpoint (default 1500), trim channels to 1500, configure stick deadband, verify behaviour when TX is off or out of range.<br /><span class=\"message-negative\">IMPORTANT:</span> Before flying read failsafe chapter of documentation and configure failsafe." "message": "Please read receiver chapter of the documentation. Configure serial port (if required), receiver mode (serial/ppm/pwm), provider (for serial receivers), bind receiver, set channel map, configure channel endpoints/range on TX so that all channels go from ~1000 to ~2000. Set midpoint (default 1500), trim channels to 1500, configure stick deadband, verify behaviour when TX is off or out of range.<br /><span class=\"message-negative\">IMPORTANT:</span> Before flying read failsafe chapter of documentation and configure failsafe."
}, },
"tuningHelp": { "tuningHelp": {
"message": "<b>Tuning tips</b><br /><span class=\"message-negative\">IMPORTANT:</span> It is important to verify motor temperatures during first flights. The higher the filter value gets the better it may fly, but you also will get more noise into the motors. <br>Default value of 100hz is optimal, but for noiser setups you can try lowering Dterm filter to 50hz and possibly also the gyro filter." "message": "<b>Tuning tips</b><br /><span class=\"message-negative\">IMPORTANT:</span> It is important to verify motor temperatures during first flights. The higher the filter value gets the better it may fly, but you also will get more noise into the motors. <br>Default value of 100Hz is optimal, but for noiser setups you can try lowering Dterm filter to 50Hz and possibly also the gyro filter."
}, },
"receiverThrottleMid": { "receiverThrottleMid": {
"message": "Throttle MID" "message": "Throttle MID"
@ -1384,6 +1446,13 @@
"message": "Preview" "message": "Preview"
}, },
"receiverMspWarningText": {
"message": "These sticks allow Betaflight to be armed and tested without a transmitter or receiver being present. However, <strong>this feature is not intended for flight and propellers must not be attached.</strong><br><br>This feature does not guarantee reliable control of your craft. <strong>Serious injury is likely to result if propellers are left on.</strong>"
},
"receiverMspEnableButton": {
"message": "Enable controls"
},
"auxiliaryHelp": { "auxiliaryHelp": {
"message": "Use ranges to define the switches on your transmitter and corresponding mode assignments. A receiver channel that gives a reading between a range min/max will activate the mode. Remember to save your settings using the Save button." "message": "Use ranges to define the switches on your transmitter and corresponding mode assignments. A receiver channel that gives a reading between a range min/max will activate the mode. Remember to save your settings using the Save button."
}, },
@ -1696,6 +1765,25 @@
"message": "Qty" "message": "Qty"
}, },
"motorsVoltage": {
"message": "Voltage:"
},
"motorsADrawing": {
"message": "Amperage:"
},
"motorsmAhDrawn": {
"message": "Amp. drawn:"
},
"motorsVoltageValue": {
"message": "$1 V"
},
"motorsADrawingValue": {
"message": "$1 A"
},
"motorsmAhDrawnValue": {
"message": "$1 mAh"
},
"motorsText":{ "motorsText":{
"message": "Motors" "message": "Motors"
}, },
@ -1768,10 +1856,10 @@
"message": "Master" "message": "Master"
}, },
"motorsNotice": { "motorsNotice": {
"message": "<strong>Motor Test Mode / Arming Notice:</strong><br />Moving the sliders or arming your craft with the transmitter will cause the motors to <strong>spin up</strong>.<br />In order to prevent injury <strong class=\"message-negative\">remove ALL propellers</strong> before using this feature.<br />" "message": "<strong>Motor Test Mode / Arming Notice:</strong><br />Moving the sliders or arming your craft with the transmitter will cause the motors to <strong>spin up</strong>.<br />In order to prevent injury <strong class=\"message-negative\">remove ALL propellers</strong> before using this feature.<br />Enabling motor test mode will also temporarily disable Runaway Takeoff Prevention, to stop it from disarming the craft when bench testing without propellers.<br />"
}, },
"motorsEnableControl": { "motorsEnableControl": {
"message": "I understand the risks, propellers are removed - Enable motor control and arming." "message": "<strong>I understand the risks</strong>, the propellers are removed - enable motor control and arming, and disable Runaway Takeoff Prevention."
}, },
"sensorsInfo": { "sensorsInfo": {
@ -2125,7 +2213,7 @@
"message": "Please do <span class=\"message-negative\">not</span> try to flash <strong>non-Betaflight</strong> hardware with this firmware flasher.<br />Do <span class=\"message-negative\">not</span> <strong>disconnect</strong> the board or <strong>turn off</strong> your computer while flashing.<br /><br /><strong>Note: </strong>STM32 bootloader is stored in ROM, it cannot be bricked.<br /><strong>Note: </strong><span class=\"message-negative\">Auto-Connect</span> is always disabled while you are inside firmware flasher.<br /><strong>Note: </strong>Make sure you have a backup; some upgrades/downgrades will wipe your configuration.<br /><strong>Note:</strong> If you have problems flashing <strong>try disconnecting all cables from your FC</strong> first, try rebooting, upgrade chrome, upgrade drivers.<br /><strong>Note:</strong> When flashing boards that have directly connected USB sockets (most newer boards) ensure you have read the USB Flashing section of the Betaflight manual and have the correct software and drivers installed" "message": "Please do <span class=\"message-negative\">not</span> try to flash <strong>non-Betaflight</strong> hardware with this firmware flasher.<br />Do <span class=\"message-negative\">not</span> <strong>disconnect</strong> the board or <strong>turn off</strong> your computer while flashing.<br /><br /><strong>Note: </strong>STM32 bootloader is stored in ROM, it cannot be bricked.<br /><strong>Note: </strong><span class=\"message-negative\">Auto-Connect</span> is always disabled while you are inside firmware flasher.<br /><strong>Note: </strong>Make sure you have a backup; some upgrades/downgrades will wipe your configuration.<br /><strong>Note:</strong> If you have problems flashing <strong>try disconnecting all cables from your FC</strong> first, try rebooting, upgrade chrome, upgrade drivers.<br /><strong>Note:</strong> When flashing boards that have directly connected USB sockets (most newer boards) ensure you have read the USB Flashing section of the Betaflight manual and have the correct software and drivers installed"
}, },
"firmwareFlasherRecoveryHead": { "firmwareFlasherRecoveryHead": {
"message": "<strong>Recovery / Lost communication<strong>" "message": "<strong>Recovery / Lost communication</strong>"
}, },
"firmwareFlasherRecoveryText": { "firmwareFlasherRecoveryText": {
"message": "If you have lost communication with your board follow these steps to restore communication: <ul><li>Power off</li><li>Enable 'No reboot sequence', enable 'Full chip erase'.</li><li>Jumper the BOOT pins or hold BOOT button.</li><li>Power on (activity LED will NOT flash if done correctly).</li><li>Install all STM32 drivers and Zadig if required (see <a href=\"https://github.com/betaflight/betaflight/wiki/Installing-Betaflight\"target=\"_blank\">USB Flashing</a> section of Betaflight manual).</li><li>Close configurator, Close all running chrome instances, Close all Chrome apps, Restart Configurator.</li><li>Release BOOT button if your FC has one.</li><li>Flash with correct firmware (using manual baud rate if specified in your FC's manual).</li><li>Power off.</li><li>Remove BOOT jumper.</li><li>Power on (activity LED should flash).</li><li>Connect normally.</li></ul>" "message": "If you have lost communication with your board follow these steps to restore communication: <ul><li>Power off</li><li>Enable 'No reboot sequence', enable 'Full chip erase'.</li><li>Jumper the BOOT pins or hold BOOT button.</li><li>Power on (activity LED will NOT flash if done correctly).</li><li>Install all STM32 drivers and Zadig if required (see <a href=\"https://github.com/betaflight/betaflight/wiki/Installing-Betaflight\"target=\"_blank\">USB Flashing</a> section of Betaflight manual).</li><li>Close configurator, Close all running chrome instances, Close all Chrome apps, Restart Configurator.</li><li>Release BOOT button if your FC has one.</li><li>Flash with correct firmware (using manual baud rate if specified in your FC's manual).</li><li>Power off.</li><li>Remove BOOT jumper.</li><li>Power on (activity LED should flash).</li><li>Connect normally.</li></ul>"
@ -2136,6 +2224,9 @@
"firmwareFlasherFirmwareNotLoaded": { "firmwareFlasherFirmwareNotLoaded": {
"message": "Firmware not loaded" "message": "Firmware not loaded"
}, },
"firmwareFlasherFirmwareLocalLoaded": {
"message": "Loaded Local Firmware: ($1 bytes)"
},
"firmwareFlasherHexCorrupted": { "firmwareFlasherHexCorrupted": {
"message": "HEX file appears to be corrupted" "message": "HEX file appears to be corrupted"
}, },
@ -2167,6 +2258,34 @@
"ledStripButtonSave": { "ledStripButtonSave": {
"message": "Save" "message": "Save"
}, },
"ledStripColorSetupTitle": {
"message": "Color setup",
"description": "Color setup title of the led strip"
},
"ledStripH": {
"message": "H",
"description": "Abbreviation of Hue in HSV (Hue, Saturation, Brightness) color model"
},
"ledStripS": {
"message": "S",
"description": "Abbreviation of Saturation in HSV (Hue, Saturation, Brightness) color model"
},
"ledStripV": {
"message": "V",
"description": "Abbreviation of Brightness in HSV (Hue, Saturation, Brightness) color model"
},
"ledStripRemainingText": {
"message": "Remaining",
"description": "In the LED STRIP, text next the counter of leds remaining"
},
"ledStripClearSelectedButton": {
"message": "Clear selected",
"description": "In the LED STRIP, clear selected leds"
},
"ledStripClearAllButton": {
"message": "Clear ALL",
"description": "In the LED STRIP, clear all leds"
},
"ledStripEepromSaved": { "ledStripEepromSaved": {
"message": "EEPROM <span class=\"message-positive\">saved</span>" "message": "EEPROM <span class=\"message-positive\">saved</span>"
}, },
@ -2179,11 +2298,147 @@
"ledStripFunctionTitle": { "ledStripFunctionTitle": {
"message": "Function" "message": "Function"
}, },
"ledStripFunctionNoneOption": {
"message": "None",
"description": "One of the modes of the Led Strip"
},
"ledStripFunctionColorOption": {
"message": "Color",
"description": "One of the modes of the Led Strip"
},
"ledStripFunctionModesOption": {
"message": "Modes &amp; Orientation",
"description": "One of the modes of the Led Strip"
},
"ledStripFunctionArmOption": {
"message": "Arm State",
"description": "One of the modes of the Led Strip"
},
"ledStripFunctionBatteryOption": {
"message": "Battery",
"description": "One of the modes of the Led Strip"
},
"ledStripFunctionRSSIOption": {
"message": "RSSI",
"description": "One of the modes of the Led Strip"
},
"ledStripFunctionGPSOption": {
"message": "GPS",
"description": "One of the modes of the Led Strip"
},
"ledStripFunctionRingOption": {
"message": "Ring",
"description": "One of the modes of the Led Strip"
},
"ledStripColorModifierTitle": { "ledStripColorModifierTitle": {
"message": "Color modifier" "message": "Color modifier"
}, },
"ledStripThrottleFunction": { "ledStripModeColorsTitle": {
"message": "Throttle" "message": "Mode colors"
},
"ledStripModeColorsModeOrientation": {
"message": "Orientation",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeHeadfree": {
"message": "Headfree",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeHorizon": {
"message": "Horizon",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeAngle": {
"message": "Angle",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeMag": {
"message": "Mag",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeBaro": {
"message": "Baro",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripDirN": {
"message": "N",
"description": "North direction in Color Mode in Led Strip"
},
"ledStripDirE": {
"message": "E",
"description": "East direction in Color Mode in Led Strip"
},
"ledStripDirS": {
"message": "S",
"description": "South direction in Color Mode in Led Strip"
},
"ledStripDirW": {
"message": "W",
"description": "West direction in Color Mode in Led Strip"
},
"ledStripDirU": {
"message": "U",
"description": "Up direction in Color Mode in Led Strip"
},
"ledStripDirD": {
"message": "D",
"description": "Down direction in Color Mode in Led Strip"
},
"ledStripModesOrientationTitle": {
"message": "LED Orientation ('Modes &amp; Orientation') and Color",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModesSpecialColorsTitle": {
"message": "Special colors",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeDisarmed": {
"message": "Disarmed",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeArmed": {
"message": "Armed",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeAnimation": {
"message": "Animation",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeBlinkBg": {
"message": "Blink background",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeGPSNoSats": {
"message": "GPS: no sats",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeGPSNoLock": {
"message": "GPS: no lock",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripModeColorsModeGPSLocked": {
"message": "GPS: locked",
"description": "One of the modes in Color Mode in Led Strip"
},
"ledStripWiring": {
"message": "LED Strip Wiring",
"description": "One of the modes in Led Strip"
},
"ledStripWiringMode": {
"message": "Wire Ordering Mode",
"description": "One of the wiring modes in Led Strip"
},
"ledStripWiringClearControl": {
"message": "Clear selected",
"description": "Control button in the wiring modes in Led Strip"
},
"ledStripWiringClearAllControl": {
"message": "Clear ALL Wiring",
"description": "Control button in the wiring modes in Led Strip"
},
"ledStripWiringMessage": {
"message": "LEDs without wire ordering number will not be saved.",
"description": "Message in the wiring modes in Led Strip"
}, },
"ledStripVtxFunction": { "ledStripVtxFunction": {
"message": "Larson scanner" "message": "Larson scanner"
@ -2388,7 +2643,7 @@
"message": "Gyro Notch Filter Cutoff 2 Frequency [Hz]" "message": "Gyro Notch Filter Cutoff 2 Frequency [Hz]"
}, },
"pidTuningGyroNotchCutoffHelp": { "pidTuningGyroNotchCutoffHelp": {
"message": "Gyro Notch Filter Cutoff Frequency in Hz (This is where notch filter starts. For example with notch filter 160 and notch hz of 260 it means the range is 160-360hz with most attenuation around center)" "message": "Gyro Notch Filter Cutoff Frequency in Hz (This is where notch filter starts. For example with notch filter 160 and notch Hz of 260 it means the range is 160-360Hz with most attenuation around center)"
}, },
"pidTuningFilterSettings": { "pidTuningFilterSettings": {
"message": "Filter Settings" "message": "Filter Settings"
@ -2418,7 +2673,7 @@
"message": "D Term Notch Filter Cutoff [Hz]" "message": "D Term Notch Filter Cutoff [Hz]"
}, },
"pidTuningDTermNotchCutoffHelp": { "pidTuningDTermNotchCutoffHelp": {
"message": "D Term Notch Filter Cutoff in Hz (This is where notch filter starts. For example with notch filter 160 and notch hz of 260 it means the range is 160-360hz with most attenuation around center)" "message": "D Term Notch Filter Cutoff in Hz (This is where notch filter starts. For example with notch filter 160 and notch Hz of 260 it means the range is 160-360Hz with most attenuation around center)"
}, },
"pidTuningYawLowpassFrequency": { "pidTuningYawLowpassFrequency": {
"message": "Yaw Lowpass Frequency [Hz]" "message": "Yaw Lowpass Frequency [Hz]"
@ -2810,6 +3065,12 @@
"osdSetupCustomLogoColorMapError": { "osdSetupCustomLogoColorMapError": {
"message": "The image contains an invalid color palette (only green, black and white are allowed)" "message": "The image contains an invalid color palette (only green, black and white are allowed)"
}, },
"osdSetupReplaceLogoImageSizeError": {
"message": "Invalid image size; expected $1×$2 instead of $3×$4"
},
"osdSetupReplaceLogoImageColorsError": {
"message": "The image contains an invalid color palette (only green, black and white are allowed)"
},
"osdSetupUploadFont": { "osdSetupUploadFont": {
"message": "Upload Font" "message": "Upload Font"
}, },
@ -3029,6 +3290,10 @@
"osdDescStatRtcDateTime": { "osdDescStatRtcDateTime": {
"message": "Date and time from real time clock" "message": "Date and time from real time clock"
}, },
"osdDescStatBattery": {
"message": "Voltage of the battery in real time"
},
"osdTimerSource": { "osdTimerSource": {
"message": "Source:" "message": "Source:"
@ -3067,6 +3332,9 @@
"osdWarningCrashFlipMode": { "osdWarningCrashFlipMode": {
"message": "Warns when flip over after crash mode is activated" "message": "Warns when flip over after crash mode is activated"
}, },
"osdWarningEscFail": {
"message": "Enumerates a list with the ESCs/motors that are failing (RPM or temperature are out of the configured threshold)"
},
"osdSectionHelpElements": { "osdSectionHelpElements": {
"message": "Enable or disable OSD elements." "message": "Enable or disable OSD elements."
@ -3127,7 +3395,7 @@
"message": "The maximum frequency for the PID loop is limited by the maximum frequency that updates can be sent by the chosen ESC / motor protocol." "message": "The maximum frequency for the PID loop is limited by the maximum frequency that updates can be sent by the chosen ESC / motor protocol."
}, },
"configurationGyroUse32kHz": { "configurationGyroUse32kHz": {
"message": "Enable gyro 32khz sampling mode" "message": "Enable gyro 32kHz sampling mode"
}, },
"configurationGyroUse32kHzHelp": { "configurationGyroUse32kHzHelp": {
"message": "32 kHz gyro update frequency is only possible if the gyro chip supports it (currently MPU6500, MPU9250, and ICM20xxx if connected over SPI). If in doubt, consult the specification for your board." "message": "32 kHz gyro update frequency is only possible if the gyro chip supports it (currently MPU6500, MPU9250, and ICM20xxx if connected over SPI). If in doubt, consult the specification for your board."

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3384
locales/it/messages.json Normal file

File diff suppressed because it is too large Load diff

3399
locales/ja/messages.json Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3384
locales/lv/messages.json Normal file

File diff suppressed because it is too large Load diff

3399
locales/pt/messages.json Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"minimum_chrome_version": "38", "minimum_chrome_version": "38",
"version": "10.2.0", "version": "10.3.0",
"author": "Betaflight Squad", "author": "Betaflight Squad",
"name": "Betaflight - Configurator", "name": "Betaflight - Configurator",
"short_name": "Betaflight", "short_name": "Betaflight",
@ -45,7 +45,7 @@
"partitions": [ "partitions": [
{ {
"name": "map", "name": "map",
"accessible_resources" : ["tabs/map.html", "tabs/map.js", "/images/icons/cf_icon_position.png"] "accessible_resources" : ["tabs/map.html", "js/tabs/map.js", "/images/icons/cf_icon_position.png"]
} }
] ]
}, },

7
package-lock.json generated
View file

@ -1,6 +1,6 @@
{ {
"name": "betaflight-configurator", "name": "betaflight-configurator",
"version": "10.2.0", "version": "10.3.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -4295,6 +4295,11 @@
"object-visit": "1.0.1" "object-visit": "1.0.1"
} }
}, },
"marked": {
"version": "0.3.12",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.12.tgz",
"integrity": "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA=="
},
"matchdep": { "matchdep": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",

View file

@ -1,7 +1,7 @@
{ {
"name": "betaflight-configurator", "name": "betaflight-configurator",
"description": "Crossplatform configuration tool for Betaflight flight control system.", "description": "Crossplatform configuration tool for Betaflight flight control system.",
"version": "10.2.0", "version": "10.3.0",
"main": "main_nwjs.html", "main": "main_nwjs.html",
"bg-script": "js/eventPage.js", "bg-script": "js/eventPage.js",
"default_locale": "en", "default_locale": "en",
@ -25,7 +25,7 @@
"name": "map", "name": "map",
"accessible_resources": [ "accessible_resources": [
"tabs/map.html", "tabs/map.html",
"tabs/map.js", "js/tabs/map.js",
"/images/icons/cf_icon_position.png" "/images/icons/cf_icon_position.png"
] ]
} }
@ -35,7 +35,8 @@
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"i18next": "^10.3.0", "i18next": "^10.3.0",
"i18next-xhr-backend": "^1.5.1" "i18next-xhr-backend": "^1.5.1",
"marked": "^0.3.12"
}, },
"devDependencies": { "devDependencies": {
"command-exists": "^1.2.2", "command-exists": "^1.2.2",

View file

@ -108,6 +108,23 @@
background-color: #00D800; background-color: #00D800;
} }
/* Power info */
.tab-motors .power_info {
float: left;
margin-left: 1em;
}
.tab-motors .power_info .power_text {
font-weight: bold;
}
.tab-motors .power_info .power_value {
margin-right: 10px;
width: 50px;
display: inline-block;
text-align: right;
}
/*Motors*/ /*Motors*/
.tab-motors svg { .tab-motors svg {

View file

@ -111,6 +111,11 @@
border-radius: 4px; border-radius: 4px;
} }
.tab-onboard_logging .dataflash-free,
.tab-onboard_logging .sdcard-free {
direction: rtl;
}
.tab-onboard_logging progress::-webkit-progress-bar { .tab-onboard_logging progress::-webkit-progress-bar {
height: 24px; height: 24px;
background-color: #eee; background-color: #eee;

View file

@ -14,9 +14,11 @@ function startApplication() {
innerBounds: { innerBounds: {
minWidth: 1024, minWidth: 1024,
minHeight: 550 minHeight: 550
}, }
icon: 'images/bf_icon_128.png'
}, function (createdWindow) { }, function (createdWindow) {
if (getChromeVersion() >= 54) {
createdWindow.icon = 'images/bf_icon_128.png';
}
createdWindow.onClosed.addListener(function () { createdWindow.onClosed.addListener(function () {
// automatically close the port when application closes // automatically close the port when application closes
// save connectionId in separate variable before createdWindow.contentWindow is destroyed // save connectionId in separate variable before createdWindow.contentWindow is destroyed
@ -122,3 +124,9 @@ function getManifestVersion(manifest) {
return version; return version;
} }
function getChromeVersion () {
var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
return raw ? parseInt(raw[2], 10) : false;
}

View file

@ -61,26 +61,28 @@ var DEFAULT;
var FC = { var FC = {
resetState: function() { resetState: function() {
CONFIG = { CONFIG = {
apiVersion: "0.0.0", apiVersion: "0.0.0",
flightControllerIdentifier: '', flightControllerIdentifier: '',
flightControllerVersion: '', flightControllerVersion: '',
version: 0, version: 0,
buildInfo: '', buildInfo: '',
multiType: 0, multiType: 0,
msp_version: 0, // not specified using semantic versioning msp_version: 0, // not specified using semantic versioning
capability: 0, capability: 0,
cycleTime: 0, cycleTime: 0,
i2cError: 0, i2cError: 0,
activeSensors: 0, activeSensors: 0,
mode: 0, mode: 0,
profile: 0, profile: 0,
uid: [0, 0, 0], uid: [0, 0, 0],
accelerometerTrims: [0, 0], accelerometerTrims: [0, 0],
name: '', name: '',
numProfiles: 3, numProfiles: 3,
rateProfile: 0, rateProfile: 0,
boardType: 0, boardType: 0,
armingDisableFlags: 0, armingDisableFlags: 0,
armingDisabled: false,
runawayTakeoffPreventionDisabled: false,
}; };
BF_CONFIG = { BF_CONFIG = {
@ -102,6 +104,7 @@ var FC = {
BEEPER_CONFIG = { BEEPER_CONFIG = {
beepers: 0, beepers: 0,
dshotBeaconTone: 0,
}; };
MIXER_CONFIG = { MIXER_CONFIG = {

View file

@ -6,7 +6,7 @@
var i18n = {} var i18n = {}
const languagesAvailables = ['ca', 'de', 'en', 'es', 'fr', 'ko', 'zh_CN']; const languagesAvailables = ['ca', 'de', 'en', 'es', 'fr', 'it', 'ja', 'ko', 'lv', 'pt', 'zh_CN'];
/** /**
* Functions that depend on the i18n framework * Functions that depend on the i18n framework
@ -39,9 +39,19 @@ i18n.init = function(cb) {
} }
i18n.getMessage = function(messageID, parameters) { i18n.getMessage = function(messageID, parameters) {
var translatedString = i18next.t(messageID + '.message');
if (parameters !== undefined) { var translatedString;
// Option 1, no parameters or Object as parameters (i18Next type parameters)
if ((parameters === undefined) || ((parameters.constructor !== Array) && (parameters instanceof Object))) {
translatedString = i18next.t(messageID + '.message', parameters);
// Option 2: parameters as $1, $2, etc.
// (deprecated, from the old Chrome i18n
} else {
translatedString = i18next.t(messageID + '.message');
if (parameters.constructor !== Array) { if (parameters.constructor !== Array) {
parameters = [parameters]; parameters = [parameters];
} }
@ -123,7 +133,28 @@ function getValidLocale(userLocale) {
if (userLocale == 'DEFAULT') { if (userLocale == 'DEFAULT') {
userLocale = window.navigator.userLanguage || window.navigator.language; userLocale = window.navigator.userLanguage || window.navigator.language;
console.log('Detected locale ' + userLocale);
// The i18next can fallback automatically to the dialect, but needs to be used with hyphen and
// we use underscore because the eventPage.js uses Chrome localization that needs underscore.
// If at some moment we get rid of the Chrome localization we can remove all of this
userLocale = userLocale.replace('-','_');
// Locale not found
if (languagesAvailables.indexOf(userLocale) == -1) {
// Is a composite locale?
var underscorePosition = userLocale.indexOf('_');
if (underscorePosition != -1) {
userLocale = userLocale.substring(0, underscorePosition);
// Locale dialect fallback not found
if (languagesAvailables.indexOf(userLocale) == -1) {
userLocale = 'en'; // Fallback language
}
} else {
userLocale = 'en';
}
}
} }
return userLocale; return userLocale;
} }

View file

@ -18,7 +18,9 @@ function startProcess() {
i18n.localizePage(); i18n.localizePage();
// alternative - window.navigator.appVersion.match(/Chrome\/([0-9.]*)/)[1]; // alternative - window.navigator.appVersion.match(/Chrome\/([0-9.]*)/)[1];
GUI.log(i18n.getMessage('infoVersions',[GUI.operating_system, window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/, "$1"), getManifestVersion()])); GUI.log(i18n.getMessage('infoVersions',{operatingSystem: GUI.operating_system,
chromeVersion: window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/, "$1"),
configuratorVersion: getManifestVersion()}));
$('#logo .version').text(getManifestVersion()); $('#logo .version').text(getManifestVersion());
updateStatusBarVersion(); updateStatusBarVersion();
@ -429,7 +431,7 @@ function notifyOutdatedVersion(releaseData) {
$('.dialogConfiguratorUpdate-websitebtn').click(function() { $('.dialogConfiguratorUpdate-websitebtn').click(function() {
dialog.close(); dialog.close();
window.open(versions[0].html_url); window.open(versions[0].html_url, '_blank');
}); });
dialog.showModal(); dialog.showModal();

View file

@ -24,7 +24,8 @@ function MspHelper () {
'TBS_SMARTAUDIO': 11, 'TBS_SMARTAUDIO': 11,
'TELEMETRY_IBUS': 12, 'TELEMETRY_IBUS': 12,
'IRC_TRAMP': 13, 'IRC_TRAMP': 13,
'RUNCAM_DEVICE_CONTROL': 14 // support communitate with RunCam Device 'RUNCAM_DEVICE_CONTROL': 14, // support communitate with RunCam Device
'LIDAR_TF': 15
}; };
} }
@ -601,6 +602,9 @@ MspHelper.prototype.process_data = function(dataHandler) {
case MSPCodes.MSP_BEEPER_CONFIG: case MSPCodes.MSP_BEEPER_CONFIG:
BEEPER_CONFIG.beepers.setMask(data.readU32()); BEEPER_CONFIG.beepers.setMask(data.readU32());
if (semver.gte(CONFIG.apiVersion, "1.37.0")) {
BEEPER_CONFIG.dshotBeaconTone = data.readU8();
}
break; break;
case MSPCodes.MSP_BOARD_ALIGNMENT_CONFIG: case MSPCodes.MSP_BOARD_ALIGNMENT_CONFIG:
@ -1200,6 +1204,9 @@ MspHelper.prototype.crunch = function(code) {
case MSPCodes.MSP_SET_BEEPER_CONFIG: case MSPCodes.MSP_SET_BEEPER_CONFIG:
var beeperMask = BEEPER_CONFIG.beepers.getMask(); var beeperMask = BEEPER_CONFIG.beepers.getMask();
buffer.push32(beeperMask); buffer.push32(beeperMask);
if (semver.gte(CONFIG.apiVersion, "1.37.0")) {
buffer.push8(BEEPER_CONFIG.dshotBeaconTone );
}
break; break;
case MSPCodes.MSP_SET_MIXER_CONFIG: case MSPCodes.MSP_SET_MIXER_CONFIG:
buffer.push8(MIXER_CONFIG.mixer) buffer.push8(MIXER_CONFIG.mixer)
@ -1525,12 +1532,21 @@ MspHelper.prototype.crunch = function(code) {
break; break;
case MSPCodes.MSP_ARMING_DISABLE: case MSPCodes.MSP_ARMING_DISABLE:
var value; var value;
if (CONFIG.arming_disabled) { if (CONFIG.armingDisabled) {
value = 1; value = 1;
} else { } else {
value = 0; value = 0;
} }
buffer.push8(value); buffer.push8(value);
if (CONFIG.runawayTakeoffPreventionDisabled) {
value = 1;
} else {
value = 0;
}
// This will be ignored if `armingDisabled` is true
buffer.push8(value);
break; break;
default: default:
return false; return false;
@ -2022,13 +2038,19 @@ MspHelper.prototype.sendRxFailConfig = function(onCompleteCallback) {
} }
} }
MspHelper.prototype.setArmingEnabled = function(doEnable, onCompleteCallback) { MspHelper.prototype.setArmingEnabled = function(doEnable, disableRunawayTakeoffPrevention, onCompleteCallback) {
if (semver.gte(CONFIG.apiVersion, "1.37.0") && (doEnable === CONFIG.arming_disabled)) { if (semver.gte(CONFIG.apiVersion, "1.37.0") && (CONFIG.armingDisabled === doEnable || CONFIG.runawayTakeoffPreventionDisabled !== disableRunawayTakeoffPrevention)) {
CONFIG.arming_disabled = !doEnable; CONFIG.armingDisabled = !doEnable;
CONFIG.runawayTakeoffPreventionDisabled = disableRunawayTakeoffPrevention;
MSP.send_message(MSPCodes.MSP_ARMING_DISABLE, mspHelper.crunch(MSPCodes.MSP_ARMING_DISABLE), false, function () { MSP.send_message(MSPCodes.MSP_ARMING_DISABLE, mspHelper.crunch(MSPCodes.MSP_ARMING_DISABLE), false, function () {
if (doEnable) { if (doEnable) {
GUI.log(i18n.getMessage('armingEnabled')); GUI.log(i18n.getMessage('armingEnabled'));
if (disableRunawayTakeoffPrevention) {
GUI.log(i18n.getMessage('runawayTakeoffPreventionDisabled'));
} else {
GUI.log(i18n.getMessage('runawayTakeoffPreventionEnabled'));
}
} else { } else {
GUI.log(i18n.getMessage('armingDisabled')); GUI.log(i18n.getMessage('armingDisabled'));
} }

View file

@ -119,7 +119,8 @@ var serial = {
case 'break': // This seems to be the error that is thrown under NW.js in Windows when the device reboots after typing 'exit' in CLI case 'break': // This seems to be the error that is thrown under NW.js in Windows when the device reboots after typing 'exit' in CLI
case 'device_lost': case 'device_lost':
CONFIG.arming_disabled = false; CONFIG.armingDisabled = false;
CONFIG.runawayTakeoffPreventionDisabled = false;
if (GUI.connected_to || GUI.connecting_to) { if (GUI.connected_to || GUI.connecting_to) {
$('a.connect').click(); $('a.connect').click();

View file

@ -72,7 +72,7 @@ function initializeSerialBackend() {
finishClose(toggleStatus); finishClose(toggleStatus);
} }
mspHelper.setArmingEnabled(true, onFinishCallback); mspHelper.setArmingEnabled(true, false, onFinishCallback);
} }
} }
} }
@ -227,8 +227,8 @@ function onOpen(openInfo) {
MSP.send_message(MSPCodes.MSP_NAME, false, false, function () { MSP.send_message(MSPCodes.MSP_NAME, false, false, function () {
GUI.log(i18n.getMessage('craftNameReceived', [CONFIG.name])); GUI.log(i18n.getMessage('craftNameReceived', [CONFIG.name]));
CONFIG.arming_disabled = false; CONFIG.armingDisabled = false;
mspHelper.setArmingEnabled(false, finishOpen); mspHelper.setArmingEnabled(false, false, finishOpen);
}); });
} else { } else {
finishOpen(); finishOpen();

View file

@ -235,7 +235,38 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
FEATURE_CONFIG.features.generateElements(features_e); FEATURE_CONFIG.features.generateElements(features_e);
// Beeper // Dshot Beeper
var dshotBeeper_e = $('.tab-configuration .dshotbeeper');
var dshotBeacon_e = $('.tab-configuration .dshotbeacon');
var dshotBeeperSwitch = $('#dshotBeeperSwitch');
var dshotBeeperBeaconTone = $('#dshotBeeperBeaconTone');
dshotBeeperSwitch.change(function() {
if ($(this).is(':checked')) {
dshotBeacon_e.show();
if (dshotBeeperBeaconTone.val() == 0) {
dshotBeeperBeaconTone.val(1).change();
}
} else {
dshotBeeperBeaconTone.val(0).change();
dshotBeacon_e.hide();
}
});
dshotBeeperBeaconTone.change(function() {
BEEPER_CONFIG.dshotBeaconTone = dshotBeeperBeaconTone.val();
});
dshotBeeperBeaconTone.val(BEEPER_CONFIG.dshotBeaconTone);
dshotBeeperSwitch.prop('checked', BEEPER_CONFIG.dshotBeaconTone !== 0).change();
if (semver.gte(CONFIG.apiVersion, "1.37.0")) {
dshotBeeper_e.show();
} else {
dshotBeeper_e.hide();
}
// Analog Beeper
var template = $('.beepers .beeper-template'); var template = $('.beepers .beeper-template');
var destination = $('.beepers .beeper-configuration'); var destination = $('.beepers .beeper-configuration');
var beeper_e = $('.tab-configuration .beepers'); var beeper_e = $('.tab-configuration .beepers');
@ -545,7 +576,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
} }
if (semver.gte(CONFIG.apiVersion, "1.24.0")) { if (semver.gte(CONFIG.apiVersion, "1.24.0")) {
serialRXtypes.push('Spektrum Bidir SRXL'); serialRXtypes.push('SPEKTRUM2048/SRXL');
} }
if (semver.gte(CONFIG.apiVersion, "1.35.0")) { if (semver.gte(CONFIG.apiVersion, "1.35.0")) {
@ -585,7 +616,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
spiRxTypes.push( spiRxTypes.push(
'FRSKY_X', 'FRSKY_X',
'A7105_FLYSKY', 'A7105_FLYSKY',
'A7105_FLYSKY_2A' 'A7105_FLYSKY_2A',
'NRF24_KN'
); );
} }

View file

@ -206,7 +206,7 @@ TABS.firmware_flasher.initialize = function (callback) {
if (parsed_hex) { if (parsed_hex) {
$('a.flash_firmware').removeClass('disabled'); $('a.flash_firmware').removeClass('disabled');
$('span.progressLabel').text('Loaded Local Firmware: (' + parsed_hex.bytes_total + ' bytes)'); $('span.progressLabel').text(i18n.getMessage('firmwareFlasherFirmwareLocalLoaded', parsed_hex.bytes_total));
} else { } else {
$('span.progressLabel').text(i18n.getMessage('firmwareFlasherHexCorrupted')); $('span.progressLabel').text(i18n.getMessage('firmwareFlasherHexCorrupted'));
} }
@ -260,8 +260,12 @@ TABS.firmware_flasher.initialize = function (callback) {
$('div.release_info .status').text(summary.status); $('div.release_info .status').text(summary.status);
$('div.release_info .file').text(summary.file).prop('href', summary.url); $('div.release_info .file').text(summary.file).prop('href', summary.url);
var formattedNotes = summary.notes.trim('\r').replace(/\r/g, '<br />'); var formattedNotes = summary.notes.replace(/#(\d+)/g, '[#$1](https://github.com/betaflight/betaflight/pull/$1)');
formattedNotes = marked(formattedNotes);
$('div.release_info .notes').html(formattedNotes); $('div.release_info .notes').html(formattedNotes);
$('div.release_info .notes').find('a').each(function() {
$(this).attr('target', '_blank');
});
$('div.release_info').slideDown(); $('div.release_info').slideDown();

View file

@ -230,6 +230,11 @@ TABS.motors.initialize = function (callback) {
accel_offset = [0, 0, 0], accel_offset = [0, 0, 0],
accel_offset_established = false; accel_offset_established = false;
// cached elements
var motor_voltage_e = $('.motors-bat-voltage'),
motor_mah_drawing_e = $('.motors-bat-mah-drawing'),
motor_mah_drawn_e = $('.motors-bat-mah-drawn');
var raw_data_text_ements = { var raw_data_text_ements = {
x: [], x: [],
@ -310,7 +315,7 @@ TABS.motors.initialize = function (callback) {
var rate = parseInt($('.tab-motors select[name="rate"]').val(), 10); var rate = parseInt($('.tab-motors select[name="rate"]').val(), 10);
var scale = parseFloat($('.tab-motors select[name="scale"]').val()); var scale = parseFloat($('.tab-motors select[name="scale"]').val());
GUI.interval_kill_all(['motor_and_status_pull']); GUI.interval_kill_all(['motor_and_status_pull','motors_power_data_pull_slow']);
switch(TABS.motors.sensor) { switch(TABS.motors.sensor) {
case "gyro": case "gyro":
@ -393,6 +398,15 @@ TABS.motors.initialize = function (callback) {
} }
}); });
// Amperage
function power_data_pull() {
motor_voltage_e.text(i18n.getMessage('motorsVoltageValue', [ANALOG.voltage]));
motor_mah_drawing_e.text(i18n.getMessage('motorsADrawingValue', [ANALOG.amperage.toFixed(2)]));
motor_mah_drawn_e.text(i18n.getMessage('motorsmAhDrawnValue', [ANALOG.mAhdrawn]));
}
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 () {
gyro_max_read = [0, 0, 0]; gyro_max_read = [0, 0, 0];
accel_max_read = [0, 0, 0]; accel_max_read = [0, 0, 0];
@ -485,7 +499,7 @@ TABS.motors.initialize = function (callback) {
$('div.sliders input').trigger('input'); $('div.sliders input').trigger('input');
mspHelper.setArmingEnabled(enabled); mspHelper.setArmingEnabled(enabled, enabled);
}).change(); }).change();
var buffering_set_motor = [], var buffering_set_motor = [],

View file

@ -180,7 +180,14 @@ TABS.onboard_logging.initialize = function (callback) {
// Offer a reasonable choice of logging rates (if people want weird steps they can use CLI) // Offer a reasonable choice of logging rates (if people want weird steps they can use CLI)
var loggingRates = []; var loggingRates = [];
var pidRate = 8000 / PID_ADVANCED_CONFIG.gyro_sync_denom / PID_ADVANCED_CONFIG.pid_process_denom; var pidRateBase = 8000;
if (PID_ADVANCED_CONFIG.gyroUse32kHz !== 0) {
pidRateBase = 32000;
}
var pidRate = pidRateBase / PID_ADVANCED_CONFIG.gyro_sync_denom /
PID_ADVANCED_CONFIG.pid_process_denom;
if (semver.gte(CONFIG.apiVersion, "1.36.0")) { if (semver.gte(CONFIG.apiVersion, "1.36.0")) {
loggingRates = [ loggingRates = [

View file

@ -1,6 +1,7 @@
'use strict'; 'use strict';
var SYM = SYM || {}; var SYM = SYM || {};
SYM.BLANK = 0x20;
SYM.VOLT = 0x06; SYM.VOLT = 0x06;
SYM.RSSI = 0x01; SYM.RSSI = 0x01;
SYM.AH_RIGHT = 0x02; SYM.AH_RIGHT = 0x02;
@ -587,6 +588,7 @@ OSD.constants = {
name: 'MAIN_BATT_VOLTAGE', name: 'MAIN_BATT_VOLTAGE',
desc: 'osdDescElementMainBattVoltage', desc: 'osdDescElementMainBattVoltage',
default_position: -29, default_position: -29,
draw_order: 20,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.BATTERY) + '16.8' + FONT.symbol(SYM.VOLT) preview: FONT.symbol(SYM.BATTERY) + '16.8' + FONT.symbol(SYM.VOLT)
}, },
@ -594,6 +596,7 @@ OSD.constants = {
name: 'RSSI_VALUE', name: 'RSSI_VALUE',
desc: 'osdDescElementRssiValue', desc: 'osdDescElementRssiValue',
default_position: -59, default_position: -59,
draw_order: 30,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.RSSI) + '99' preview: FONT.symbol(SYM.RSSI) + '99'
}, },
@ -607,6 +610,7 @@ OSD.constants = {
name: 'THROTTLE_POSITION', name: 'THROTTLE_POSITION',
desc: 'osdDescElementThrottlePosition', desc: 'osdDescElementThrottlePosition',
default_position: -9, default_position: -9,
draw_order: 110,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.THR) + FONT.symbol(SYM.THR1) + '69' preview: FONT.symbol(SYM.THR) + FONT.symbol(SYM.THR1) + '69'
}, },
@ -619,6 +623,7 @@ OSD.constants = {
VTX_CHANNEL: { VTX_CHANNEL: {
name: 'VTX_CHANNEL', name: 'VTX_CHANNEL',
default_position: 1, default_position: 1,
draw_order: 120,
positionable: true, positionable: true,
preview: 'R:2:1' preview: 'R:2:1'
}, },
@ -639,31 +644,88 @@ OSD.constants = {
name: 'DISARMED', name: 'DISARMED',
desc: 'osdDescElementDisarmed', desc: 'osdDescElementDisarmed',
default_position: -109, default_position: -109,
draw_order: 280,
positionable: true, positionable: true,
preview: 'DISARMED' preview: 'DISARMED'
}, },
CROSSHAIRS: { CROSSHAIRS: {
name: 'CROSSHAIRS', name: 'CROSSHAIRS',
desc: 'osdDescElementCrosshairs', desc: 'osdDescElementCrosshairs',
default_position: -1, default_position: 193,
positionable: false draw_order: 40,
positionable: function() {
return semver.gte(CONFIG.apiVersion, "1.38.0") ? true : false;
},
preview: FONT.symbol(SYM.AH_CENTER_LINE) + FONT.symbol(SYM.AH_CENTER) + FONT.symbol(SYM.AH_CENTER_LINE_RIGHT)
}, },
ARTIFICIAL_HORIZON: { ARTIFICIAL_HORIZON: {
name: 'ARTIFICIAL_HORIZON', name: 'ARTIFICIAL_HORIZON',
desc: 'osdDescElementArtificialHorizon', desc: 'osdDescElementArtificialHorizon',
default_position: -1, default_position: 194,
positionable: false draw_order: 10,
positionable: function() {
return semver.gte(CONFIG.apiVersion, "1.38.0") ? true : false;
},
preview: function() {
var artificialHorizon = new Array();
for (var j = 1; j < 8; j++) {
for (var i = -4; i <= 4; i++) {
var element;
// Blank char to mark the size of the element
if (j != 4) {
element = {x: i, y : j, sym : SYM.BLANK};
// Sample of horizon
} else {
element = {x: i, y : j, sym : SYM.AH_BAR9_0 + 4};
}
artificialHorizon.push(element);
}
}
return artificialHorizon;
}
}, },
HORIZON_SIDEBARS: { HORIZON_SIDEBARS: {
name: 'HORIZON_SIDEBARS', name: 'HORIZON_SIDEBARS',
desc: 'osdDescElementHorizonSidebars', desc: 'osdDescElementHorizonSidebars',
default_position: -1, default_position: 194,
positionable: false draw_order: 50,
positionable: function() {
return semver.gte(CONFIG.apiVersion, "1.38.0") ? true : false;
},
preview: function(fieldPosition) {
var horizonSidebar = new Array();
var hudwidth = OSD.constants.AHISIDEBARWIDTHPOSITION;
var hudheight = OSD.constants.AHISIDEBARHEIGHTPOSITION;
for (var i = -hudheight; i <= hudheight; i++) {
var element = {x: -hudwidth, y : i, sym : SYM.AH_DECORATION};
horizonSidebar.push(element);
element = {x: hudwidth, y : i, sym : SYM.AH_DECORATION};
horizonSidebar.push(element);
}
// AH level indicators
var element = {x: -hudwidth + 1, y : 0, sym : SYM.AH_LEFT};
horizonSidebar.push(element);
element = {x: hudwidth - 1, y : 0, sym : SYM.AH_RIGHT};
horizonSidebar.push(element);
return horizonSidebar;
}
}, },
CURRENT_DRAW: { CURRENT_DRAW: {
name: 'CURRENT_DRAW', name: 'CURRENT_DRAW',
desc: 'osdDescElementCurrentDraw', desc: 'osdDescElementCurrentDraw',
default_position: -23, default_position: -23,
draw_order: 130,
positionable: true, positionable: true,
preview: function() { preview: function() {
return semver.gte(CONFIG.apiVersion, "1.36.0") ? ' 42.00' + FONT.symbol(SYM.AMP) : FONT.symbol(SYM.AMP) + '42.0'; return semver.gte(CONFIG.apiVersion, "1.36.0") ? ' 42.00' + FONT.symbol(SYM.AMP) : FONT.symbol(SYM.AMP) + '42.0';
@ -673,6 +735,7 @@ OSD.constants = {
name: 'MAH_DRAWN', name: 'MAH_DRAWN',
desc: 'osdDescElementMahDrawn', desc: 'osdDescElementMahDrawn',
default_position: -18, default_position: -18,
draw_order: 140,
positionable: true, positionable: true,
preview: function() { preview: function() {
return semver.gte(CONFIG.apiVersion, "1.36.0") ? ' 690' + FONT.symbol(SYM.MAH) : FONT.symbol(SYM.MAH) + '690'; return semver.gte(CONFIG.apiVersion, "1.36.0") ? ' 690' + FONT.symbol(SYM.MAH) : FONT.symbol(SYM.MAH) + '690';
@ -682,6 +745,7 @@ OSD.constants = {
name: 'CRAFT_NAME', name: 'CRAFT_NAME',
desc: 'osdDescElementCraftName', desc: 'osdDescElementCraftName',
default_position: -77, default_position: -77,
draw_order: 150,
positionable: true, positionable: true,
preview: function(osd_data) { preview: function(osd_data) {
return OSD.generateCraftName(osd_data, 1); return OSD.generateCraftName(osd_data, 1);
@ -691,6 +755,7 @@ OSD.constants = {
name: 'ALTITUDE', name: 'ALTITUDE',
desc: 'osdDescElementAltitude', desc: 'osdDescElementAltitude',
default_position: 62, default_position: 62,
draw_order: 160,
positionable: true, positionable: true,
preview: function(osd_data) { preview: function(osd_data) {
return '399.7' + FONT.symbol(osd_data.unit_mode === 0 ? SYM.FEET : SYM.METRE) return '399.7' + FONT.symbol(osd_data.unit_mode === 0 ? SYM.FEET : SYM.METRE)
@ -714,6 +779,7 @@ OSD.constants = {
name: 'FLYMODE', name: 'FLYMODE',
desc: 'osdDescElementFlyMode', desc: 'osdDescElementFlyMode',
default_position: -1, default_position: -1,
draw_order: 90,
positionable: true, positionable: true,
preview: 'STAB' preview: 'STAB'
}, },
@ -721,6 +787,7 @@ OSD.constants = {
name: 'GPS_SPEED', name: 'GPS_SPEED',
desc: 'osdDescElementGPSSpeed', desc: 'osdDescElementGPSSpeed',
default_position: -1, default_position: -1,
draw_order: 330,
positionable: true, positionable: true,
preview: ' 40K' preview: ' 40K'
}, },
@ -728,6 +795,7 @@ OSD.constants = {
name: 'GPS_SATS', name: 'GPS_SATS',
desc: 'osdDescElementGPSSats', desc: 'osdDescElementGPSSats',
default_position: -1, default_position: -1,
draw_order: 320,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.GPS_SAT_L) + FONT.symbol(SYM.GPS_SAT_R) + '14' preview: FONT.symbol(SYM.GPS_SAT_L) + FONT.symbol(SYM.GPS_SAT_R) + '14'
}, },
@ -735,6 +803,7 @@ OSD.constants = {
name: 'GPS_LON', name: 'GPS_LON',
desc: 'osdDescElementGPSLon', desc: 'osdDescElementGPSLon',
default_position: -1, default_position: -1,
draw_order: 350,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.ARROW_SOUTH) + '00.00000000' preview: FONT.symbol(SYM.ARROW_SOUTH) + '00.00000000'
}, },
@ -742,6 +811,7 @@ OSD.constants = {
name: 'GPS_LAT', name: 'GPS_LAT',
desc: 'osdDescElementGPSLat', desc: 'osdDescElementGPSLat',
default_position: -1, default_position: -1,
draw_order: 340,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.ARROW_EAST) + '00.00000000' preview: FONT.symbol(SYM.ARROW_EAST) + '00.00000000'
}, },
@ -749,6 +819,7 @@ OSD.constants = {
name: 'DEBUG', name: 'DEBUG',
desc: 'osdDescElementDebug', desc: 'osdDescElementDebug',
default_position: -1, default_position: -1,
draw_order: 240,
positionable: true, positionable: true,
preview: 'DBG 0 0 0 0' preview: 'DBG 0 0 0 0'
}, },
@ -756,6 +827,7 @@ OSD.constants = {
name: 'PID_ROLL', name: 'PID_ROLL',
desc: 'osdDescElementPIDRoll', desc: 'osdDescElementPIDRoll',
default_position: 0x800 | (10 << 5) | 2, // 0x0800 | (y << 5) | x default_position: 0x800 | (10 << 5) | 2, // 0x0800 | (y << 5) | x
draw_order: 170,
positionable: true, positionable: true,
preview: 'ROL 43 40 20' preview: 'ROL 43 40 20'
}, },
@ -763,6 +835,7 @@ OSD.constants = {
name: 'PID_PITCH', name: 'PID_PITCH',
desc: 'osdDescElementPIDPitch', desc: 'osdDescElementPIDPitch',
default_position: 0x800 | (11 << 5) | 2, // 0x0800 | (y << 5) | x default_position: 0x800 | (11 << 5) | 2, // 0x0800 | (y << 5) | x
draw_order: 180,
positionable: true, positionable: true,
preview: 'PIT 58 50 22' preview: 'PIT 58 50 22'
}, },
@ -770,6 +843,7 @@ OSD.constants = {
name: 'PID_YAW', name: 'PID_YAW',
desc: 'osdDescElementPIDYaw', desc: 'osdDescElementPIDYaw',
default_position: 0x800 | (12 << 5) | 2, // 0x0800 | (y << 5) | x default_position: 0x800 | (12 << 5) | 2, // 0x0800 | (y << 5) | x
draw_order: 190,
positionable: true, positionable: true,
preview: 'YAW 70 45 20' preview: 'YAW 70 45 20'
}, },
@ -777,6 +851,7 @@ OSD.constants = {
name: 'POWER', name: 'POWER',
desc: 'osdDescElementPower', desc: 'osdDescElementPower',
default_position: (15 << 5) | 2, default_position: (15 << 5) | 2,
draw_order: 200,
positionable: true, positionable: true,
preview: function() { preview: function() {
return semver.gte(CONFIG.apiVersion, "1.36.0") ? ' 142W' : '142W'; return semver.gte(CONFIG.apiVersion, "1.36.0") ? ' 142W' : '142W';
@ -786,6 +861,7 @@ OSD.constants = {
name: 'PID_RATE_PROFILE', name: 'PID_RATE_PROFILE',
desc: 'osdDescElementPIDRateProfile', desc: 'osdDescElementPIDRateProfile',
default_position: 0x800 | (13 << 5) | 2, // 0x0800 | (y << 5) | x default_position: 0x800 | (13 << 5) | 2, // 0x0800 | (y << 5) | x
draw_order: 210,
positionable: true, positionable: true,
preview: '1-2' preview: '1-2'
}, },
@ -800,6 +876,7 @@ OSD.constants = {
name: 'AVG_CELL_VOLTAGE', name: 'AVG_CELL_VOLTAGE',
desc: 'osdDescElementAvgCellVoltage', desc: 'osdDescElementAvgCellVoltage',
default_position: 12 << 5, default_position: 12 << 5,
draw_order: 230,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.BATTERY) + '3.98' + FONT.symbol(SYM.VOLT) preview: FONT.symbol(SYM.BATTERY) + '3.98' + FONT.symbol(SYM.VOLT)
}, },
@ -807,6 +884,7 @@ OSD.constants = {
name: 'PITCH_ANGLE', name: 'PITCH_ANGLE',
desc: 'osdDescElementPitchAngle', desc: 'osdDescElementPitchAngle',
default_position: -1, default_position: -1,
draw_order: 250,
positionable: true, positionable: true,
preview: '-00.0' preview: '-00.0'
}, },
@ -814,6 +892,7 @@ OSD.constants = {
name: 'ROLL_ANGLE', name: 'ROLL_ANGLE',
desc: 'osdDescElementRollAngle', desc: 'osdDescElementRollAngle',
default_position: -1, default_position: -1,
draw_order: 260,
positionable: true, positionable: true,
preview: '-00.0' preview: '-00.0'
}, },
@ -821,6 +900,7 @@ OSD.constants = {
name: 'MAIN_BATT_USAGE', name: 'MAIN_BATT_USAGE',
desc: 'osdDescElementMainBattUsage', desc: 'osdDescElementMainBattUsage',
default_position: -17, default_position: -17,
draw_order: 270,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.PB_START) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_END) + FONT.symbol(SYM.PB_EMPTY) + FONT.symbol(SYM.PB_CLOSE) preview: FONT.symbol(SYM.PB_START) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_END) + FONT.symbol(SYM.PB_EMPTY) + FONT.symbol(SYM.PB_CLOSE)
}, },
@ -835,6 +915,7 @@ OSD.constants = {
name: 'HOME_DIRECTION', name: 'HOME_DIRECTION',
desc: 'osdDescElementHomeDirection', desc: 'osdDescElementHomeDirection',
default_position: -1, default_position: -1,
draw_order: 370,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.ARROW_SOUTH + 2) preview: FONT.symbol(SYM.ARROW_SOUTH + 2)
}, },
@ -842,6 +923,7 @@ OSD.constants = {
name: 'HOME_DISTANCE', name: 'HOME_DISTANCE',
desc: 'osdDescElementHomeDistance', desc: 'osdDescElementHomeDistance',
default_position: -1, default_position: -1,
draw_order: 360,
positionable: true, positionable: true,
preview: function(osd_data) { preview: function(osd_data) {
return '43' + FONT.symbol(osd_data.unit_mode === 0 ? SYM.FEET : SYM.METRE) return '43' + FONT.symbol(osd_data.unit_mode === 0 ? SYM.FEET : SYM.METRE)
@ -851,6 +933,7 @@ OSD.constants = {
name: 'NUMERICAL_HEADING', name: 'NUMERICAL_HEADING',
desc: 'osdDescElementNumericalHeading', desc: 'osdDescElementNumericalHeading',
default_position: -1, default_position: -1,
draw_order: 290,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.ARROW_EAST) + '90' preview: FONT.symbol(SYM.ARROW_EAST) + '90'
}, },
@ -858,6 +941,7 @@ OSD.constants = {
name: 'NUMERICAL_VARIO', name: 'NUMERICAL_VARIO',
desc: 'osdDescElementNumericalVario', desc: 'osdDescElementNumericalVario',
default_position: -1, default_position: -1,
draw_order: 300,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.ARROW_NORTH) + '8.7' preview: FONT.symbol(SYM.ARROW_NORTH) + '8.7'
}, },
@ -865,6 +949,7 @@ OSD.constants = {
name: 'COMPASS_BAR', name: 'COMPASS_BAR',
desc: 'osdDescElementCompassBar', desc: 'osdDescElementCompassBar',
default_position: -1, default_position: -1,
draw_order: 310,
positionable: true, positionable: true,
preview: function(osd_data) { preview: function(osd_data) {
return FONT.symbol(SYM.HEADING_W) + FONT.symbol(SYM.HEADING_LINE) + FONT.symbol(SYM.HEADING_DIVIDED_LINE) + return FONT.symbol(SYM.HEADING_W) + FONT.symbol(SYM.HEADING_LINE) + FONT.symbol(SYM.HEADING_DIVIDED_LINE) +
@ -876,6 +961,7 @@ OSD.constants = {
name: 'WARNINGS', name: 'WARNINGS',
desc: 'osdDescElementWarnings', desc: 'osdDescElementWarnings',
default_position: -1, default_position: -1,
draw_order: 220,
positionable: true, positionable: true,
preview: 'LOW VOLTAGE' preview: 'LOW VOLTAGE'
}, },
@ -883,6 +969,7 @@ OSD.constants = {
name: 'ESC_TEMPERATURE', name: 'ESC_TEMPERATURE',
desc: 'osdDescElementEscTemperature', desc: 'osdDescElementEscTemperature',
default_position: -1, default_position: -1,
draw_order: 380,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.TEMP_C) + '45' preview: FONT.symbol(SYM.TEMP_C) + '45'
}, },
@ -890,6 +977,7 @@ OSD.constants = {
name: 'ESC_RPM', name: 'ESC_RPM',
desc: 'osdDescElementEscRpm', desc: 'osdDescElementEscRpm',
default_position: -1, default_position: -1,
draw_order: 390,
positionable: true, positionable: true,
preview: '226000' preview: '226000'
}, },
@ -897,6 +985,7 @@ OSD.constants = {
name: 'REMAINING_TIME_ESTIMATE', name: 'REMAINING_TIME_ESTIMATE',
desc: 'osdDescElementRemaningTimeEstimate', desc: 'osdDescElementRemaningTimeEstimate',
default_position: -1, default_position: -1,
draw_order: 80,
positionable: true, positionable: true,
preview: '01:13' preview: '01:13'
}, },
@ -904,6 +993,7 @@ OSD.constants = {
name: 'RTC_DATE_TIME', name: 'RTC_DATE_TIME',
desc: 'osdDescElementRtcDateTime', desc: 'osdDescElementRtcDateTime',
default_position: -1, default_position: -1,
draw_order: 400,
positionable: true, positionable: true,
preview: '2017-11-11 16:20:00' preview: '2017-11-11 16:20:00'
}, },
@ -911,6 +1001,7 @@ OSD.constants = {
name: 'ADJUSTMENT_RANGE', name: 'ADJUSTMENT_RANGE',
desc: 'osdDescElementAdjustmentRange', desc: 'osdDescElementAdjustmentRange',
default_position: -1, default_position: -1,
draw_order: 410,
positionable: true, positionable: true,
preview: 'PITCH/ROLL P: 42' preview: 'PITCH/ROLL P: 42'
}, },
@ -918,6 +1009,7 @@ OSD.constants = {
name: 'TIMER_1', name: 'TIMER_1',
desc: 'osdDescElementTimer1', desc: 'osdDescElementTimer1',
default_position: -1, default_position: -1,
draw_order: 60,
positionable: true, positionable: true,
preview: function(osd_data) { preview: function(osd_data) {
return OSD.generateTimerPreview(osd_data, 0); return OSD.generateTimerPreview(osd_data, 0);
@ -927,6 +1019,7 @@ OSD.constants = {
name: 'TIMER_2', name: 'TIMER_2',
desc: 'osdDescElementTimer2', desc: 'osdDescElementTimer2',
default_position: -1, default_position: -1,
draw_order: 70,
positionable: true, positionable: true,
preview: function(osd_data) { preview: function(osd_data) {
return OSD.generateTimerPreview(osd_data, 1); return OSD.generateTimerPreview(osd_data, 1);
@ -936,6 +1029,7 @@ OSD.constants = {
name: 'CORE_TEMPERATURE', name: 'CORE_TEMPERATURE',
desc: 'osdDescElementCoreTemperature', desc: 'osdDescElementCoreTemperature',
default_position: -1, default_position: -1,
draw_order: 420,
positionable: true, positionable: true,
preview: function(osd_data) { preview: function(osd_data) {
return OSD.generateTemperaturePreview(osd_data, 33); return OSD.generateTemperaturePreview(osd_data, 33);
@ -1009,6 +1103,10 @@ OSD.constants = {
RTC_DATE_TIME: { RTC_DATE_TIME: {
name: 'RTC_DATE_TIME', name: 'RTC_DATE_TIME',
desc: 'osdDescStatRtcDateTime' desc: 'osdDescStatRtcDateTime'
},
STAT_BATTERY: {
name: 'STAT_BATTERY',
desc: 'osdDescStatBattery'
} }
}, },
ALL_WARNINGS: { ALL_WARNINGS: {
@ -1035,7 +1133,12 @@ OSD.constants = {
CRASH_FLIP_MODE: { CRASH_FLIP_MODE: {
name: 'CRASH_FLIP_MODE', name: 'CRASH_FLIP_MODE',
desc: 'osdWarningCrashFlipMode' desc: 'osdWarningCrashFlipMode'
},
ESC_FAIL: {
name: 'OSD_WARNING_ESC_FAIL',
desc: 'osdWarningEscFail'
} }
}, },
FONT_TYPES: [ FONT_TYPES: [
{ file: "default", name: "Default" }, { file: "default", name: "Default" },
@ -1048,6 +1151,20 @@ OSD.constants = {
] ]
}; };
OSD.searchLimitsElement = function(arrayElements) {
// Search minimum and maximum
var limits = {minX: 0, maxX: 0, minY:0, maxY: 0};
arrayElements.forEach(function(valor, indice, array) {
limits.minX = Math.min(valor.x, limits.minX);
limits.maxX = Math.max(valor.x, limits.maxX);
limits.minY = Math.min(valor.y, limits.minY);
limits.maxY = Math.max(valor.y, limits.maxY);
});
return limits;
}
// Pick display fields by version, order matters, so these are going in an array... pry could iterate the example map instead // Pick display fields by version, order matters, so these are going in an array... pry could iterate the example map instead
OSD.chooseFields = function () { OSD.chooseFields = function () {
var F = OSD.constants.ALL_DISPLAY_FIELDS; var F = OSD.constants.ALL_DISPLAY_FIELDS;
@ -1176,6 +1293,11 @@ OSD.chooseFields = function () {
OSD.constants.STATISTIC_FIELDS = OSD.constants.STATISTIC_FIELDS.concat([ OSD.constants.STATISTIC_FIELDS = OSD.constants.STATISTIC_FIELDS.concat([
F.RTC_DATE_TIME F.RTC_DATE_TIME
]); ]);
if (semver.gte(CONFIG.apiVersion, "1.38.0")) {
OSD.constants.STATISTIC_FIELDS = OSD.constants.STATISTIC_FIELDS.concat([
F.STAT_BATTERY
]);
}
} }
// Choose warnings // Choose warnings
@ -1189,6 +1311,11 @@ OSD.chooseFields = function () {
F.VISUAL_BEEPER, F.VISUAL_BEEPER,
F.CRASH_FLIP_MODE F.CRASH_FLIP_MODE
]; ];
if (semver.gte(CONFIG.apiVersion, "1.39.0")) {
OSD.constants.WARNINGS = OSD.constants.WARNINGS.concat([
F.ESC_FAIL
]);
}
}; };
OSD.updateDisplaySize = function() { OSD.updateDisplaySize = function() {
@ -1204,6 +1331,24 @@ OSD.updateDisplaySize = function() {
}; };
}; };
OSD.drawByOrder = function(selectedPosition, field, charCode) {
// Check if there is other field at the same position
if (OSD.data.preview[selectedPosition] !== undefined) {
var oldField = OSD.data.preview[selectedPosition][0];
if (oldField != null) {
if (oldField.draw_order !== undefined) {
if ((field.draw_order === undefined) || (field.draw_order < oldField.draw_order)) {
// Not overwrite old field
return;
}
}
}
// Default action, overwrite old field
OSD.data.preview[selectedPosition++] = [field, charCode];
}
}
OSD.msp = { OSD.msp = {
/** /**
@ -1363,6 +1508,7 @@ OSD.msp = {
name: suffix ? c.name + suffix : c.name, name: suffix ? c.name + suffix : c.name,
desc: c.desc, desc: c.desc,
index: j, index: j,
draw_order: c.draw_order,
positionable: c.positionable, positionable: c.positionable,
preview: suffix ? c.preview + suffix : c.preview preview: suffix ? c.preview + suffix : c.preview
}, this.helpers.unpack.position(v, c))); }, this.helpers.unpack.position(v, c)));
@ -1417,11 +1563,14 @@ OSD.msp = {
} }
} }
// Generate OSD element previews that are defined by a function // Generate OSD element previews and positionable that are defined by a function
for (let item of d.display_items) { for (let item of d.display_items) {
if (typeof(item.preview) === 'function') { if (typeof(item.preview) === 'function') {
item.preview = item.preview(d); item.preview = item.preview(d);
} }
if (typeof(item.positionable) === 'function') {
item.positionable = item.positionable(d);
}
} }
OSD.updateDisplaySize(); OSD.updateDisplaySize();
@ -1440,8 +1589,18 @@ OSD.GUI.preview = {
}, },
onDragStart: function(e) { onDragStart: function(e) {
var ev = e.originalEvent; var ev = e.originalEvent;
var display_item = OSD.data.display_items[$(ev.target).data('field').index];
var offsetX = 6;
var offsetY = 9;
if (display_item.preview.constructor === Array) {
var arrayElements = display_item.preview;
var limits = OSD.searchLimitsElement(arrayElements);
offsetX -= limits.minX*12;
offsetY -= limits.minY*12;
}
ev.dataTransfer.setData("text/plain", $(ev.target).data('field').index); ev.dataTransfer.setData("text/plain", $(ev.target).data('field').index);
ev.dataTransfer.setDragImage($(this).data('field').preview_img, 6, 9); ev.dataTransfer.setDragImage($(this).data('field').preview_img, offsetX, offsetY);
}, },
onDragOver: function(e) { onDragOver: function(e) {
var ev = e.originalEvent; var ev = e.originalEvent;
@ -1460,10 +1619,35 @@ OSD.GUI.preview = {
var position = $(this).removeAttr('style').data('position'); var position = $(this).removeAttr('style').data('position');
var field_id = parseInt(ev.dataTransfer.getData('text/plain')) var field_id = parseInt(ev.dataTransfer.getData('text/plain'))
var display_item = OSD.data.display_items[field_id]; var display_item = OSD.data.display_items[field_id];
var overflows_line = FONT.constants.SIZES.LINE - ((position % FONT.constants.SIZES.LINE) + display_item.preview.length);
if (overflows_line < 0) { var overflows_line = 0;
position += overflows_line; // Standard preview, string type
if (display_item.preview.constructor !== Array) {
overflows_line = FONT.constants.SIZES.LINE - ((position % FONT.constants.SIZES.LINE) + display_item.preview.length);
if (overflows_line < 0) {
position += overflows_line;
}
// Advanced preview, array type
} else {
var arrayElements = display_item.preview;
var limits = OSD.searchLimitsElement(arrayElements);
var selectedPositionX = position % FONT.constants.SIZES.LINE;
var selectedPositionY = Math.trunc(position / FONT.constants.SIZES.LINE);
if ((limits.minX < 0) && ((selectedPositionX + limits.minX) < 0)) {
position += Math.abs(selectedPositionX + limits.minX);
} else if ((limits.maxX > 0) && ((selectedPositionX + limits.maxX) >= FONT.constants.SIZES.LINE)) {
position -= (selectedPositionX + limits.maxX + 1) - FONT.constants.SIZES.LINE;
}
if ((limits.minY < 0) && ((selectedPositionY + limits.minY) < 0)) {
position += Math.abs(selectedPositionY + limits.minY)*FONT.constants.SIZES.LINE;
} else if ((limits.maxY > 0) && ((selectedPositionY + limits.maxY) >= OSD.data.display_size.y)) {
position -= (selectedPositionY + limits.maxY - OSD.data.display_size.y + 1)*FONT.constants.SIZES.LINE;
}
} }
if (semver.gte(CONFIG.apiVersion, "1.21.0")) { if (semver.gte(CONFIG.apiVersion, "1.21.0")) {
// unsigned now // unsigned now
} else { } else {
@ -1846,53 +2030,75 @@ TABS.osd.initialize = function (callback) {
OSD.data.preview[i * 30 + j] = [{name: 'LOGO', positionable: false}, x++]; OSD.data.preview[i * 30 + j] = [{name: 'LOGO', positionable: false}, x++];
} }
} }
// draw all the displayed items and the drag and drop preview images // draw all the displayed items and the drag and drop preview images
for(let field of OSD.data.display_items) { for(let field of OSD.data.display_items) {
if (!field.preview || !field.isVisible) { continue; }
var j = (field.position >= 0) ? field.position : field.position + OSD.data.display_size.total; if (!field.preview || !field.isVisible) {
continue;
}
var selectedPosition = (field.position >= 0) ? field.position : field.position + OSD.data.display_size.total;
// create the preview image // create the preview image
field.preview_img = new Image(); field.preview_img = new Image();
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d"); var ctx = canvas.getContext("2d");
// fill the screen buffer
for(var i = 0; i < field.preview.length; i++) { // Standard preview, type String
var charCode = field.preview.charCodeAt(i); if (field.preview.constructor !== Array) {
OSD.data.preview[j++] = [field, charCode];
// draw the preview
var img = new Image(); // fill the screen buffer
img.src = FONT.draw(charCode); for(var i = 0; i < field.preview.length; i++) {
ctx.drawImage(img, i*12, 0);
// Add the character to the preview
var charCode = field.preview.charCodeAt(i);
OSD.drawByOrder(selectedPosition++, field, charCode);
// Image used when "dragging" the element
if (field.positionable) {
var img = new Image();
img.src = FONT.draw(charCode);
ctx.drawImage(img, i*12, 0);
}
}
} else {
var arrayElements = field.preview;
// The array can have negative and positive positions, search limits...
var limits = OSD.searchLimitsElement(arrayElements);
var offsetX = 0;
var offsetY = 0;
if (limits.minX < 0) {
offsetX = -limits.minX;
}
if (limits.minY < 0) {
offsetY = -limits.minY;
}
for (var i=0; i < arrayElements.length; i++) {
// Add the character to the preview
var element = arrayElements[i];
var charCode = element.sym;
OSD.drawByOrder(selectedPosition + element.x + element.y*FONT.constants.SIZES.LINE, field, charCode);
// Image used when "dragging" the element
if (field.positionable) {
var img = new Image();
img.src = FONT.draw(charCode);
ctx.drawImage(img, (element.x + offsetX)*12, (element.y + offsetY)*12);
}
}
} }
field.preview_img.src = canvas.toDataURL('image/png'); field.preview_img.src = canvas.toDataURL('image/png');
// Required for NW.js - Otherwise the <img /> will // Required for NW.js - Otherwise the <img /> will
// consume drag/drop events. //consume drag/drop events.
field.preview_img.style.pointerEvents = 'none'; field.preview_img.style.pointerEvents = 'none';
}
var centerishPosition = 194;
// artificial horizon
if ($('input[name="ARTIFICIAL_HORIZON"]').prop('checked')) {
for (var i = 0; i < 9; i++) {
OSD.data.preview[centerishPosition - 4 + i] = SYM.AH_BAR9_0 + 4;
}
}
// crosshairs
if ($('input[name="CROSSHAIRS"]').prop('checked')) {
OSD.data.preview[centerishPosition - 1] = SYM.AH_CENTER_LINE;
OSD.data.preview[centerishPosition + 1] = SYM.AH_CENTER_LINE_RIGHT;
OSD.data.preview[centerishPosition] = SYM.AH_CENTER;
}
// sidebars
if ($('input[name="HORIZON_SIDEBARS"]').prop('checked')) {
var hudwidth = OSD.constants.AHISIDEBARWIDTHPOSITION;
var hudheight = OSD.constants.AHISIDEBARHEIGHTPOSITION;
for (var i = -hudheight; i <= hudheight; i++) {
OSD.data.preview[centerishPosition - hudwidth + (i * FONT.constants.SIZES.LINE)] = SYM.AH_DECORATION;
OSD.data.preview[centerishPosition + hudwidth + (i * FONT.constants.SIZES.LINE)] = SYM.AH_DECORATION;
}
// AH level indicators
OSD.data.preview[centerishPosition-hudwidth+1] = SYM.AH_LEFT;
OSD.data.preview[centerishPosition+hudwidth-1] = SYM.AH_RIGHT;
} }
// render // render
var $preview = $('.display-layout .preview').empty(); var $preview = $('.display-layout .preview').empty();
var $row = $('<div class="row"/>'); var $row = $('<div class="row"/>');

View file

@ -236,8 +236,18 @@ TABS.pid_tuning.initialize = function (callback) {
$('.pid_filter input[name="dTermNotchFrequency"]').val(FILTER_CONFIG.dterm_notch_hz); $('.pid_filter input[name="dTermNotchFrequency"]').val(FILTER_CONFIG.dterm_notch_hz);
$('.pid_filter input[name="dTermNotchCutoff"]').val(FILTER_CONFIG.dterm_notch_cutoff); $('.pid_filter input[name="dTermNotchCutoff"]').val(FILTER_CONFIG.dterm_notch_cutoff);
$('input[name="dtermSetpointTransition-number"]').val(ADVANCED_TUNING.dtermSetpointTransition / 100); var dtermSetpointTransitionNumberElement = $('input[name="dtermSetpointTransition-number"]');
$('input[name="dtermSetpointTransition-range"]').val(ADVANCED_TUNING.dtermSetpointTransition / 100); var dtermSetpointTransitionRangeElement = $('input[name="dtermSetpointTransition-range"]');
if (semver.gte(CONFIG.apiVersion, "1.38.0")) {
dtermSetpointTransitionNumberElement.attr('min', 0.00);
dtermSetpointTransitionRangeElement.attr('min', 0.00);
} else {
dtermSetpointTransitionNumberElement.attr('min', 0.01);
dtermSetpointTransitionRangeElement.attr('min', 0.01);
}
dtermSetpointTransitionNumberElement.val(ADVANCED_TUNING.dtermSetpointTransition / 100);
dtermSetpointTransitionRangeElement.val(ADVANCED_TUNING.dtermSetpointTransition / 100);
$('input[name="dtermSetpoint-number"]').val(ADVANCED_TUNING.dtermSetpointWeight / 100); $('input[name="dtermSetpoint-number"]').val(ADVANCED_TUNING.dtermSetpointWeight / 100);
$('input[name="dtermSetpoint-range"]').val(ADVANCED_TUNING.dtermSetpointWeight / 100); $('input[name="dtermSetpoint-range"]').val(ADVANCED_TUNING.dtermSetpointWeight / 100);

View file

@ -47,6 +47,10 @@ TABS.ports.initialize = function (callback, scrollPosition) {
functionRules.push({ name: 'RUNCAM_DEVICE_CONTROL', groups: ['peripherals'], maxPorts: 1 }); functionRules.push({ name: 'RUNCAM_DEVICE_CONTROL', groups: ['peripherals'], maxPorts: 1 });
} }
if (semver.gte(CONFIG.apiVersion, "1.37.0")) {
functionRules.push({ name: 'LIDAR_TF', groups: ['peripherals'], maxPorts: 1 });
}
for (var i = 0; i < functionRules.length; i++) { for (var i = 0; i < functionRules.length; i++) {
functionRules[i].displayName = i18n.getMessage('portsFunction_' + functionRules[i].name); functionRules[i].displayName = i18n.getMessage('portsFunction_' + functionRules[i].name);
} }

View file

@ -7,32 +7,32 @@ var
// What's the index of each channel in the MSP channel list? // What's the index of each channel in the MSP channel list?
channelMSPIndexes = { channelMSPIndexes = {
roll: 0, Roll: 0,
pitch: 1, Pitch: 1,
throttle: 2, Throttle: 2,
yaw: 3, Yaw: 3,
aux1: 4, Aux1: 4,
aux2: 5, Aux2: 5,
aux3: 6, Aux3: 6,
aux4: 7, Aux4: 7,
}, },
// Set reasonable initial stick positions (Mode 2) // Set reasonable initial stick positions (Mode 2)
stickValues = { stickValues = {
throttle: CHANNEL_MIN_VALUE, Throttle: CHANNEL_MIN_VALUE,
pitch: CHANNEL_MID_VALUE, Pitch: CHANNEL_MID_VALUE,
roll: CHANNEL_MID_VALUE, Roll: CHANNEL_MID_VALUE,
yaw: CHANNEL_MID_VALUE, Yaw: CHANNEL_MID_VALUE,
aux1: CHANNEL_MIN_VALUE, Aux1: CHANNEL_MIN_VALUE,
aux2: CHANNEL_MIN_VALUE, Aux2: CHANNEL_MIN_VALUE,
aux3: CHANNEL_MIN_VALUE, Aux3: CHANNEL_MIN_VALUE,
aux4: CHANNEL_MIN_VALUE Aux4: CHANNEL_MIN_VALUE
}, },
// First the vertical axis, then the horizontal: // First the vertical axis, then the horizontal:
gimbals = [ gimbals = [
["throttle", "yaw"], ["Throttle", "Yaw"],
["pitch", "roll"], ["Pitch", "Roll"],
], ],
gimbalElems, gimbalElems,
@ -40,6 +40,18 @@ var
enableTX = false; enableTX = false;
// This is a hack to get the i18n var of the parent, but the localizePage not works
const i18n = opener.i18n;
$(document).ready(function () {
$('[i18n]:not(.i18n-replaced)').each(function() {
var element = $(this);
element.html(i18n.getMessage(element.attr('i18n')));
element.addClass('i18n-replaced');
});
})
function transmitChannels() { function transmitChannels() {
var var
channelValues = [0, 0, 0, 0, 0, 0, 0, 0]; channelValues = [0, 0, 0, 0, 0, 0, 0, 0];
@ -148,7 +160,7 @@ $(document).ready(function() {
$(".slider", sliderElems).each(function(sliderIndex) { $(".slider", sliderElems).each(function(sliderIndex) {
var var
initialValue = stickValues["aux" + (sliderIndex + 1)]; initialValue = stickValues["Aux" + (sliderIndex + 1)];
$(this) $(this)
.noUiSlider({ .noUiSlider({
@ -160,7 +172,7 @@ $(document).ready(function() {
}).on('slide change set', function(e, value) { }).on('slide change set', function(e, value) {
value = Math.round(parseFloat(value)); value = Math.round(parseFloat(value));
stickValues["aux" + (sliderIndex + 1)] = value; stickValues["Aux" + (sliderIndex + 1)] = value;
$(".tooltip", this).text(value); $(".tooltip", this).text(value);
}); });

View file

@ -37,6 +37,7 @@
<link rel="stylesheet" type="text/css" href="./js/libraries/jbox/jBox.css"/> <link rel="stylesheet" type="text/css" href="./js/libraries/jbox/jBox.css"/>
<script type="text/javascript" src="./node_modules/i18next/i18next.js"></script> <script type="text/javascript" src="./node_modules/i18next/i18next.js"></script>
<script type="text/javascript" src="./node_modules/i18next-xhr-backend/i18nextXHRBackend.js"></script> <script type="text/javascript" src="./node_modules/i18next-xhr-backend/i18nextXHRBackend.js"></script>
<script type="text/javascript" src="./node_modules/marked/marked.min.js"></script>
<script type="text/javascript" src="./js/libraries/q.js"></script> <script type="text/javascript" src="./js/libraries/q.js"></script>
<script type="text/javascript" src="./js/libraries/jquery-2.1.4.min.js"></script> <script type="text/javascript" src="./js/libraries/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="./js/libraries/jquery-ui-1.11.4.min.js"></script> <script type="text/javascript" src="./js/libraries/jquery-ui-1.11.4.min.js"></script>
@ -155,10 +156,10 @@
</div> </div>
<div class="header-wrapper"> <div class="header-wrapper">
<div id="dataflash_wrapper_global"> <div id="dataflash_wrapper_global">
<div class="noflash_global" align="center">No dataflash <br>chip found</div> <div class="noflash_global" align="center" i18n="sensorDataFlashNotFound"></div>
<ul class="dataflash-contents_global"> <ul class="dataflash-contents_global">
<li class="dataflash-free_global"> <li class="dataflash-free_global">
<div class="legend">Dataflash: free space</div> <div class="legend" i18n="sensorDataFlashFreeSpace"></div>
</li> </li>
</ul> </ul>
<div id="expertMode" align="center"> <div id="expertMode" align="center">
@ -171,22 +172,22 @@
<div id="sensor-status" class="sensor_state mode-connected"> <div id="sensor-status" class="sensor_state mode-connected">
<ul> <ul>
<li class="gyro" i18n_title="sensorStatusGyro"> <li class="gyro" i18n_title="sensorStatusGyro">
<div class="gyroicon">Gyro</div> <div class="gyroicon" i18n="sensorStatusGyroShort"></div>
</li> </li>
<li class="accel" i18n_title="sensorStatusAccel"> <li class="accel" i18n_title="sensorStatusAccel">
<div class="accicon">Accel</div> <div class="accicon" i18n="sensorStatusAccelShort"></div>
</li> </li>
<li class="mag" i18n_title="sensorStatusMag"> <li class="mag" i18n_title="sensorStatusMag">
<div class="magicon">Mag</div> <div class="magicon" i18n="sensorStatusMagShort"></div>
</li> </li>
<li class="baro" i18n_title="sensorStatusBaro"> <li class="baro" i18n_title="sensorStatusBaro">
<div class="baroicon">Baro</div> <div class="baroicon" i18n="sensorStatusBaroShort"></div>
</li> </li>
<li class="gps" i18n_title="sensorStatusGPS"> <li class="gps" i18n_title="sensorStatusGPS">
<div class="gpsicon">GPS</div> <div class="gpsicon" i18n="sensorStatusGPSShort"></div>
</li> </li>
<li class="sonar" i18n_title="sensorStatusSonar"> <li class="sonar" i18n_title="sensorStatusSonar">
<div class="sonaricon">Sonar</div> <div class="sonaricon" i18n="sensorStatusSonarShort"></div>
</li> </li>
</ul> </ul>
</div> </div>
@ -208,7 +209,7 @@
<div class="clear-both"></div> <div class="clear-both"></div>
<div id="log"> <div id="log">
<div class="logswitch"> <div class="logswitch">
<a href="#" id="showlog">Show Log</a> <a href="#" id="showlog" i18n="logActionShow"></a>
</div> </div>
<div id="scrollicon"></div> <div id="scrollicon"></div>
<div class="wrapper"></div> <div class="wrapper"></div>

View file

@ -674,9 +674,56 @@
</td> </td>
</tr> </tr>
<tr class="dshotbeeper">
<td style="width:calc(50%)" colspan="2">
<!-- ROW 5 - HALF WIDTH PANE -->
<!-- DSHOT BEEPER -->
<div class="dshotBeeper" style="width: calc(50%);">
<div class="gui_box grey" style="margin-top:10px;">
<div class="gui_box_titlebar">
<div class="spacer_box_title" i18n="configurationDshotBeeper"></div>
</div>
<div class="spacer_box">
<table cellpadding="0" cellspacing="0">
<tbody class="dshot-beeper-configuration" id="noline">
<tr>
<td>
<div class="number">
<div style="float: left; height: 20px; margin-right: 34px;">
<input class="dshot-beeper toggle" id="dshotBeeperSwitch" type="checkbox" />
</div>
<label for="dshotBeeperSwitch">
<span i18n="configurationUseDshotBeeper"></span>
</label>
</div>
</td>
</tr>
<tr class="dshotbeacon">
<td>
<div class="number">
<div style="float: left; height: 20px; margin-right: 10px;">
<input type="number" id="dshotBeeperBeaconTone" step="1" min="1" max="5" />
</div>
<label for="dshotBeeperBeaconTone">
<span i18n="configurationDshotBeaconTone"></span>
</label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</td>
</tr>
<tr class="beepers"> <tr class="beepers">
<td style="width:calc(100%)" colspan="2"> <td style="width:calc(100%)" colspan="2">
<!-- ROW 4 - FULL WIDTH PANE --> <!-- ROW 6 - FULL WIDTH PANE -->
<!-- BEEPER --> <!-- BEEPER -->
<div class="beepers" style="width: calc(100%);"> <div class="beepers" style="width: calc(100%);">

View file

@ -11,7 +11,7 @@
</tr> </tr>
<tr> <tr>
<td><select name="firmware_version"> <td><select name="firmware_version">
<option value="0">Loading ...</option> <option value="0" i18n="firmwareFlasherOptionLoading">Loading ...</option>
</select></td> </select></td>
<td><span class="description" i18n="firmwareFlasherOnlineSelectFirmwareVersionDescription"></span></td> <td><span class="description" i18n="firmwareFlasherOnlineSelectFirmwareVersionDescription"></span></td>
</tr> </tr>

View file

@ -9,7 +9,7 @@
<div class="content_mid"> <div class="content_mid">
<div class="column third_left text1"> <div class="column third_left text1">
<div class="wrap"> <div class="wrap">
<h2>Hardware</h2> <h2 i18n="defaultWelcomeHead"></h2>
<div i18n="defaultWelcomeText"></div> <div i18n="defaultWelcomeText"></div>
</div> </div>
</div> </div>
@ -24,7 +24,7 @@
<h3 i18n="defaultDonateHead"></h3> <h3 i18n="defaultDonateHead"></h3>
<div i18n="defaultDonateText"></div> <div i18n="defaultDonateText"></div>
<div class="donate"> <div class="donate">
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=dreambb1982%40gmail%2ecom&lc=US&item_name=Betaflight&no_note=0&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHostedGuest" <a href="https://paypal.me/betaflight"
target="_blank" i18n_title="defaultDonate"><img src="./images/btn-donate.png" alt="Paypal" target="_blank" i18n_title="defaultDonate"><img src="./images/btn-donate.png" alt="Paypal"
height="30" /></a> height="30" /></a>
</li> </li>

View file

@ -29,19 +29,19 @@
<div class="block"></div> <div class="block"></div>
</div> </div>
<div class="colorDefineSliders"> <div class="colorDefineSliders">
<div class="">Color setup</div> <div class="" i18n="ledStripColorSetupTitle"/>
<div class="colorDefineSliderContainer"> <div class="colorDefineSliderContainer">
<Label class="colorDefineSliderLabel">H</Label> <Label class="colorDefineSliderLabel" i18n="ledStripH"></Label>
<input class="sliderHSV" type="range" min="0" max="359" value="0"> <input class="sliderHSV" type="range" min="0" max="359" value="0">
<Label class="colorDefineSliderValue Hvalue">0</Label> <Label class="colorDefineSliderValue Hvalue">0</Label>
</div> </div>
<div class="colorDefineSliderContainer"> <div class="colorDefineSliderContainer">
<Label class="colorDefineSliderLabel">S</Label> <Label class="colorDefineSliderLabel" i18n="ledStripS"></Label>
<input class="sliderHSV" type="range" min="0" max="255" value="0"> <input class="sliderHSV" type="range" min="0" max="255" value="0">
<Label class="colorDefineSliderValue Svalue">0</Label> <Label class="colorDefineSliderValue Svalue">0</Label>
</div> </div>
<div class="colorDefineSliderContainer"> <div class="colorDefineSliderContainer">
<Label class="colorDefineSliderLabel">V</Label> <Label class="colorDefineSliderLabel" i18n="ledStripV"></Label>
<input class="sliderHSV" type="range" min="0" max="255" value="0"> <input class="sliderHSV" type="range" min="0" max="255" value="0">
<Label class="colorDefineSliderValue Vvalue">0</Label> <Label class="colorDefineSliderValue Vvalue">0</Label>
</div> </div>
@ -49,10 +49,10 @@
<div class="controls"> <div class="controls">
<div class="wires-remaining"> <div class="wires-remaining">
<div></div> <div></div>
Remaining <span i18n="ledStripRemainingText"></span>
</div> </div>
<button class="funcClear">Clear selected</button> <button class="funcClear" i18n="ledStripClearSelectedButton"></button>
<button class="funcClearAll">Clear ALL</button> <button class="funcClearAll" i18n="ledStripClearAllButton"></button>
<div class="section" i18n="ledStripFunctionSection"></div> <div class="section" i18n="ledStripFunctionSection"></div>
@ -60,14 +60,14 @@
<div class="select"> <div class="select">
<span class="color_section" i18n="ledStripFunctionTitle"></span> <span class="color_section" i18n="ledStripFunctionTitle"></span>
<select class="functionSelect"> <select class="functionSelect">
<option value="">None</option> <option value="" i18n="ledStripFunctionNoneOption"/>
<option value="function-c" class="">Color</option> <option value="function-c" class="" i18n="ledStripFunctionColorOption"/>
<option value="function-f" class="">Modes &amp; Orientation</option> <option value="function-f" class="" i18n="ledStripFunctionModesOption"/>
<option value="function-a" class="">Arm State</option> <option value="function-a" class="" i18n="ledStripFunctionArmOption"/>
<option value="function-l" class="extra_functions20">Battery</option> <option value="function-l" class="extra_functions20" i18n="ledStripFunctionBatteryOption"/>
<option value="function-s" class="extra_functions20">RSSI</option> <option value="function-s" class="extra_functions20" i18n="ledStripFunctionRSSIOption"/>
<option value="function-g" class="extra_functions20">GPS</option> <option value="function-g" class="extra_functions20" i18n="ledStripFunctionGPSOption"/>
<option value="function-r" class="">Ring</option> <option value="function-r" class="" i18n="ledStripFunctionRingOption"/>
</select> </select>
</div> </div>
@ -78,20 +78,20 @@
<input type="checkbox" name="ThrottleHue" class="toggle function-t" /> <input type="checkbox" name="ThrottleHue" class="toggle function-t" />
<label> <label>
<select class="auxSelect"> <select class="auxSelect">
<option value="0" class="">Roll</option> <option value="0" class="" i18n="controlAxisRoll"/>
<option value="1" class="">Pitch</option> <option value="1" class="" i18n="controlAxisPitch"/>
<option value="2" class="">Yaw</option> <option value="2" class="" i18n="controlAxisYaw"/>
<option value="3" class="">Throttle</option> <option value="3" class="" i18n="controlAxisThrottle"/>
<option value="4" class="">Aux1</option> <option value="4" class="" i18n="controlAxisAux1"/>
<option value="5" class="">Aux2</option> <option value="5" class="" i18n="controlAxisAux2"/>
<option value="6" class="">Aux3</option> <option value="6" class="" i18n="controlAxisAux3"/>
<option value="7" class="">Aux4</option> <option value="7" class="" i18n="controlAxisAux4"/>
<option value="8" class="">Aux5</option> <option value="8" class="" i18n="controlAxisAux5"/>
<option value="9" class="">Aux6</option> <option value="9" class="" i18n="controlAxisAux6"/>
<option value="10" class="">Aux7</option> <option value="10" class="" i18n="controlAxisAux7"/>
<option value="11" class="">Aux8</option> <option value="11" class="" i18n="controlAxisAux8"/>
</select> </select>
<span class="labelSelect" i18n="ledStripThrottleFunction"></span> <span class="labelSelect" i18n="controlAxisThrottle"></span>
</label> </label>
</div> </div>
@ -130,33 +130,33 @@
</div> </div>
<div class="mode_colors"> <div class="mode_colors">
<div class="section">Mode colors</div> <div class="section" i18n="ledStripModeColorsTitle"/>
<select class="modeSelect"> <select class="modeSelect">
<option value="0">Orientation</option> <option value="0" i18n="ledStripModeColorsModeOrientation"/>
<option value="1">Headfree</option> <option value="1" i18n="ledStripModeColorsModeHeadfree"/>
<option value="2">Horizon</option> <option value="2" i18n="ledStripModeColorsModeHorizon"/>
<option value="3">Angle</option> <option value="3" i18n="ledStripModeColorsModeAngle"/>
<option value="4">Mag</option> <option value="4" i18n="ledStripModeColorsModeMag"/>
<option value="5">Baro</option> <option value="5" i18n="ledStripModeColorsModeBaro"/>
</select> </select>
<button class="mode_color-0-0 dir-n">N</button> <button class="mode_color-0-0 dir-n" i18n="ledStripDirN"/>
<button class="mode_color-0-1 dir-e">E</button> <button class="mode_color-0-1 dir-e" i18n="ledStripDirE"/>
<button class="mode_color-0-2 dir-s">S</button> <button class="mode_color-0-2 dir-s" i18n="ledStripDirS"/>
<button class="mode_color-0-3 dir-w">W</button> <button class="mode_color-0-3 dir-w" i18n="ledStripDirW"/>
<button class="mode_color-0-4 dir-u">U</button> <button class="mode_color-0-4 dir-u" i18n="ledStripDirU"/>
<button class="mode_color-0-5 dir-d">D</button> <button class="mode_color-0-5 dir-d" i18n="ledStripDirD"/>
</div> </div>
<div class="section">LED Orientation ('Modes &amp; Orientation') and Color</div> <div class="section" i18n="ledStripModesOrientationTitle"/>
<div class="directions"> <div class="directions">
<button class="dir-n">N</button> <button class="dir-n" i18n="ledStripDirN"/>
<button class="dir-e">E</button> <button class="dir-e" i18n="ledStripDirE"/>
<button class="dir-s">S</button> <button class="dir-s" i18n="ledStripDirS"/>
<button class="dir-w">W</button> <button class="dir-w" i18n="ledStripDirW"/>
<button class="dir-u">U</button> <button class="dir-u" i18n="ledStripDirU"/>
<button class="dir-d">D</button> <button class="dir-d" i18n="ledStripDirD"/>
</div> </div>
<div class="colors"> <div class="colors">
@ -179,26 +179,26 @@
</div> </div>
<div class="special_colors mode_colors"> <div class="special_colors mode_colors">
<div class="section">Special colors</div> <div class="section" i18n="ledStripModesSpecialColorsTitle"/>
<button class="mode_color-6-0" i18n_title="colorGreen">Disarmed</button> <button class="mode_color-6-0" i18n_title="colorGreen" i18n="ledStripModeColorsModeDisarmed"/>
<button class="mode_color-6-1" i18n_title="colorBlue">Armed</button> <button class="mode_color-6-1" i18n_title="colorBlue" i18n="ledStripModeColorsModeArmed"/>
<button class="mode_color-6-2" i18n_title="colorWhite">Animation</button> <button class="mode_color-6-2" i18n_title="colorWhite" i18n="ledStripModeColorsModeAnimation"/>
<!-- button class="mode_color-6-3" i18n_title="colorBlack">Background</button --> <!-- button class="mode_color-6-3" i18n_title="colorBlack">Background</button -->
<button class="mode_color-6-4" i18n_title="colorBlack">Blink background</button> <button class="mode_color-6-4" i18n_title="colorBlack" i18n="ledStripModeColorsModeBlinkBg"/>
<button class="mode_color-6-5" i18n_title="colorRed">GPS: no sats</button> <button class="mode_color-6-5" i18n_title="colorRed" i18n="ledStripModeColorsModeGPSNoSats"/>
<button class="mode_color-6-6" i18n_title="colorOrange">GPS: no lock</button> <button class="mode_color-6-6" i18n_title="colorOrange" i18n="ledStripModeColorsModeGPSNoLock"/>
<button class="mode_color-6-7" i18n_title="colorGreen">GPS: locked</button> <button class="mode_color-6-7" i18n_title="colorGreen" i18n="ledStripModeColorsModeGPSLocked"/>
</div> </div>
<div class="section">LED Strip Wiring</div> <div class="section" i18n="ledStripWiring"/>
<div class="wiringMode"> <div class="wiringMode">
<button class="funcWire w100">Wire Ordering Mode</button> <button class="funcWire w100" i18n="ledStripWiringMode"/>
</div> </div>
<div class="wiringControls"> <div class="wiringControls">
<button class="funcWireClearSelect w50">Clear selected</button> <button class="funcWireClearSelect w50" i18n="ledStripWiringClearControl"/>
<button class="funcWireClear w50">Clear ALL Wiring</button> <button class="funcWireClear w50" i18n="ledStripWiringClearAllControl"/>
</div> </div>
<p>LEDs without wire ordering number will not be saved.</p> <p i18n="ledStripWiringMessage"/>
</div> </div>
<div class="colorControls"> <div class="colorControls">

View file

@ -11,7 +11,7 @@
padding: 0px; padding: 0px;
} }
</style> </style>
<script src="map.js"></script> <script src="/js/tabs/map.js"></script>
</head> </head>
<body> <body>
<div id="map-canvas"></div> <div id="map-canvas"></div>

View file

@ -99,6 +99,13 @@
</div> </div>
</div> </div>
</div> </div>
<div class="power_info">
<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="motorsmAhDrawn" class="power_text"></span><span class="motors-bat-mah-drawn power_value"></span>
</div>
</div> </div>
</div> </div>
<div class="gui_box motorblock"> <div class="gui_box motorblock">

View file

@ -294,8 +294,8 @@
</td> </td>
</tr> </tr>
<tr class="dtermSetpoint" style="height:30px;"> <tr class="dtermSetpoint" style="height:30px;">
<td><input type="number" name="dtermSetpoint-number" step="0.01" min="0.00" max="2.55"/></td> <td><input type="number" name="dtermSetpoint-number" step="0.01" min="0.00" max="2.54"/></td>
<td class="slider"><input type="range" name="dtermSetpoint-range" step="0.01" min="0.00" max="2.55"/></td> <td class="slider"><input type="range" name="dtermSetpoint-range" step="0.01" min="0.00" max="2.54"/></td>
<td> <td>
<div> <div>
<label> <label>

View file

@ -201,7 +201,7 @@
</label> </label>
</div> </div>
<div class="number"> <div class="number">
<label> <input type="number" name="amperageoffset" step="1" min=-16000" max="16000" /> <span <label> <input type="number" name="amperageoffset" step="1" min=-32000" max="32000" /> <span
i18n="powerAmperageOffset"></span> i18n="powerAmperageOffset"></span>
</label> </label>
</div> </div>

View file

@ -1,16 +1,16 @@
<html> <html>
<head> <head>
<link type="text/css" rel="stylesheet" href="../css/opensans_webfontkit/fonts.css" media="all" /> <link type="text/css" rel="stylesheet" href="/css/opensans_webfontkit/fonts.css" media="all" />
<script type="text/javascript" src="/js/libraries/jquery-2.1.4.min.js"></script> <script type="text/javascript" src="/js/libraries/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="/js/libraries/jquery-ui-1.11.4.min.js"></script> <script type="text/javascript" src="/js/libraries/jquery-ui-1.11.4.min.js"></script>
<script type="text/javascript" src="/js/libraries/jquery.nouislider.all.min.js"></script> <script type="text/javascript" src="/js/libraries/jquery.nouislider.all.min.js"></script>
<script type="text/javascript" src="receiver_msp.js"></script> <script type="text/javascript" src="/js/tabs/receiver_msp.js"></script>
<link type="text/css" rel="stylesheet" href="/js/libraries/jquery.nouislider.min.css"> <link type="text/css" rel="stylesheet" href="/js/libraries/jquery.nouislider.min.css">
<link type="text/css" rel="stylesheet" href="/js/libraries/jquery.nouislider.pips.min.css"> <link type="text/css" rel="stylesheet" href="/js/libraries/jquery.nouislider.pips.min.css">
<link type="text/css" rel="stylesheet" href="receiver_msp.css" media="all" /> <link type="text/css" rel="stylesheet" href="/css/tabs/receiver_msp.css" media="all" />
</head> </head>
<body> <body>
<div class="control-gimbals"> <div class="control-gimbals">
@ -49,16 +49,9 @@
</div> </div>
</div> </div>
<div class="warning"> <div class="warning">
<p> <p i18n="receiverMspWarningText"></p>
These sticks allow BetaFlight to be armed and tested without a transmitter or receiver being present.
However, <strong>this feature is not intended for flight and propellers must not be attached.</strong>
</p>
<p>
This feature does not guarantee reliable control of your craft. <strong>Serious injury is likely to
result if propellers are left on.</strong>
</p>
<div class="button-enable btn"> <div class="button-enable btn">
<a class="button-enable" href="#">Enable controls</a> <a class="button-enable" href="#" i18n="receiverMspEnableButton"></a>
</div> </div>
</div> </div>
</body> </body>