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

10.3.x-maintenance
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)
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**
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
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
@ -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.
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
Terminal=false
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
file /usr/share/common-licenses/GPL-3 for more information.
Files: *
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 "French"
!insertmacro MUI_LANGUAGE "German"
!insertmacro MUI_LANGUAGE "Italian"
!insertmacro MUI_LANGUAGE "Japanese"
!insertmacro MUI_LANGUAGE "Korean"
!insertmacro MUI_LANGUAGE "Latvian"
!insertmacro MUI_LANGUAGE "Portuguese"
!insertmacro MUI_LANGUAGE "SimpChinese"
!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/';
var nwBuilderOptions = {
version: '0.27.4',
version: '0.28.3',
files: './dist/**/*',
macIcns: './src/images/bf_icon.icns',
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": {
"message": "Fran\u00e7ais (fr)"
},
"language_it": {
"message": "Italiano (it)"
},
"language_ja": {
"message": "\u65E5\u672C\u8A9E (ja)"
},
"language_ko": {
"message": "\ud55c\uad6d\uc5b4 (ko)"
},
"language_lv": {
"message": "Latvie\u0161u (lv)"
},
"language_pt": {
"message": "Portugu\u00EAs (pt)"
},
"language_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": {
"message": "Gyroscope"
},
"sensorStatusGyroShort": {
"message": "Gyro",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusAccel": {
"message": "Accelerometer"
},
"sensorStatusAccelShort": {
"message": "Accel",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusMag": {
"message": "Magnetometer"
},
"sensorStatusMagShort": {
"message": "Mag",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusBaro": {
"message": "Barometer"
},
"sensorStatusBaroShort": {
"message": "Baro",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusGPS": {
"message": "GPS"
},
"sensorStatusGPSShort": {
"message": "GPS",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"sensorStatusSonar": {
"message": "Sonar / Range finder"
},
"sensorStatusSonarShort": {
"message": "Sonar",
"description": "Text of the image in the top sensors icons. Please keep it short."
},
"checkForConfiguratorUnstableVersions": {
"message": "Show update notifications for unstable versions of the configurator"
},
@ -327,7 +371,8 @@
},
"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": {
"message" : "Loaded release information for $1 from GitHub."
@ -369,6 +414,12 @@
"armingEnabled": {
"message": "<strong>Arming Enabled</strong>"
},
"runawayTakeoffPreventionDisabled": {
"message": "<strong>Runaway Takeoff Prevention temporarily Disabled</strong>"
},
"runawayTakeoffPreventionEnabled": {
"message": "<strong>Runaway Takeoff Prevention Enabled</strong>"
},
"boardInfoReceived": {
"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>"
},
"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": {
"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": {
@ -448,7 +499,7 @@
"message": "Contributing"
},
"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": {
"message": "Changelog"
@ -913,6 +964,15 @@
"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)."
},
"configurationDshotBeeper": {
"message": "DSHOT Beacon Configuration"
},
"configurationUseDshotBeeper": {
"message": "Use DSHOT beacon (use motors to sound beeps when disarmed)"
},
"configurationDshotBeaconTone": {
"message": "Beacon Tone"
},
"configurationBeeper": {
"message": "Beeper Configuration"
},
@ -1121,13 +1181,15 @@
"portsFunction_RUNCAM_DEVICE_CONTROL": {
"message": "RunCam Device"
},
"pidTuningProfileOption": {
"message": "Profile $1"
},
"pidTuningRateProfileOption": {
"message": "Rateprofile $1"
},
"portsFunction_LIDAR_TF": {
"message": "Benewake LIDAR"
},
"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>."
},
@ -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."
},
"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": {
"message": "Throttle MID"
@ -1384,6 +1446,13 @@
"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": {
"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"
},
"motorsVoltage": {
"message": "Voltage:"
},
"motorsADrawing": {
"message": "Amperage:"
},
"motorsmAhDrawn": {
"message": "Amp. drawn:"
},
"motorsVoltageValue": {
"message": "$1 V"
},
"motorsADrawingValue": {
"message": "$1 A"
},
"motorsmAhDrawnValue": {
"message": "$1 mAh"
},
"motorsText":{
"message": "Motors"
},
@ -1768,10 +1856,10 @@
"message": "Master"
},
"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": {
"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": {
@ -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"
},
"firmwareFlasherRecoveryHead": {
"message": "<strong>Recovery / Lost communication<strong>"
"message": "<strong>Recovery / Lost communication</strong>"
},
"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>"
@ -2136,6 +2224,9 @@
"firmwareFlasherFirmwareNotLoaded": {
"message": "Firmware not loaded"
},
"firmwareFlasherFirmwareLocalLoaded": {
"message": "Loaded Local Firmware: ($1 bytes)"
},
"firmwareFlasherHexCorrupted": {
"message": "HEX file appears to be corrupted"
},
@ -2167,6 +2258,34 @@
"ledStripButtonSave": {
"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": {
"message": "EEPROM <span class=\"message-positive\">saved</span>"
},
@ -2179,11 +2298,147 @@
"ledStripFunctionTitle": {
"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": {
"message": "Color modifier"
},
"ledStripThrottleFunction": {
"message": "Throttle"
"ledStripModeColorsTitle": {
"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": {
"message": "Larson scanner"
@ -2388,7 +2643,7 @@
"message": "Gyro Notch Filter Cutoff 2 Frequency [Hz]"
},
"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": {
"message": "Filter Settings"
@ -2418,7 +2673,7 @@
"message": "D Term Notch Filter Cutoff [Hz]"
},
"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": {
"message": "Yaw Lowpass Frequency [Hz]"
@ -2810,6 +3065,12 @@
"osdSetupCustomLogoColorMapError": {
"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": {
"message": "Upload Font"
},
@ -3029,6 +3290,10 @@
"osdDescStatRtcDateTime": {
"message": "Date and time from real time clock"
},
"osdDescStatBattery": {
"message": "Voltage of the battery in real time"
},
"osdTimerSource": {
"message": "Source:"
@ -3067,6 +3332,9 @@
"osdWarningCrashFlipMode": {
"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": {
"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."
},
"configurationGyroUse32kHz": {
"message": "Enable gyro 32khz sampling mode"
"message": "Enable gyro 32kHz sampling mode"
},
"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."

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,
"minimum_chrome_version": "38",
"version": "10.2.0",
"version": "10.3.0",
"author": "Betaflight Squad",
"name": "Betaflight - Configurator",
"short_name": "Betaflight",
@ -45,7 +45,7 @@
"partitions": [
{
"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",
"version": "10.2.0",
"version": "10.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -4295,6 +4295,11 @@
"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": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",

View File

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

View File

@ -108,6 +108,23 @@
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*/
.tab-motors svg {

View File

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

View File

@ -14,9 +14,11 @@ function startApplication() {
innerBounds: {
minWidth: 1024,
minHeight: 550
},
icon: 'images/bf_icon_128.png'
}
}, function (createdWindow) {
if (getChromeVersion() >= 54) {
createdWindow.icon = 'images/bf_icon_128.png';
}
createdWindow.onClosed.addListener(function () {
// automatically close the port when application closes
// save connectionId in separate variable before createdWindow.contentWindow is destroyed
@ -122,3 +124,9 @@ function getManifestVersion(manifest) {
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 = {
resetState: function() {
CONFIG = {
apiVersion: "0.0.0",
flightControllerIdentifier: '',
flightControllerVersion: '',
version: 0,
buildInfo: '',
multiType: 0,
msp_version: 0, // not specified using semantic versioning
capability: 0,
cycleTime: 0,
i2cError: 0,
activeSensors: 0,
mode: 0,
profile: 0,
uid: [0, 0, 0],
accelerometerTrims: [0, 0],
name: '',
numProfiles: 3,
rateProfile: 0,
boardType: 0,
armingDisableFlags: 0,
apiVersion: "0.0.0",
flightControllerIdentifier: '',
flightControllerVersion: '',
version: 0,
buildInfo: '',
multiType: 0,
msp_version: 0, // not specified using semantic versioning
capability: 0,
cycleTime: 0,
i2cError: 0,
activeSensors: 0,
mode: 0,
profile: 0,
uid: [0, 0, 0],
accelerometerTrims: [0, 0],
name: '',
numProfiles: 3,
rateProfile: 0,
boardType: 0,
armingDisableFlags: 0,
armingDisabled: false,
runawayTakeoffPreventionDisabled: false,
};
BF_CONFIG = {
@ -102,6 +104,7 @@ var FC = {
BEEPER_CONFIG = {
beepers: 0,
dshotBeaconTone: 0,
};
MIXER_CONFIG = {

View File

@ -6,7 +6,7 @@
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
@ -39,9 +39,19 @@ i18n.init = function(cb) {
}
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) {
parameters = [parameters];
}
@ -123,7 +133,28 @@ function getValidLocale(userLocale) {
if (userLocale == 'DEFAULT') {
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;
}

View File

@ -18,7 +18,9 @@ function startProcess() {
i18n.localizePage();
// 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());
updateStatusBarVersion();
@ -429,7 +431,7 @@ function notifyOutdatedVersion(releaseData) {
$('.dialogConfiguratorUpdate-websitebtn').click(function() {
dialog.close();
window.open(versions[0].html_url);
window.open(versions[0].html_url, '_blank');
});
dialog.showModal();

View File

@ -24,7 +24,8 @@ function MspHelper () {
'TBS_SMARTAUDIO': 11,
'TELEMETRY_IBUS': 12,
'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:
BEEPER_CONFIG.beepers.setMask(data.readU32());
if (semver.gte(CONFIG.apiVersion, "1.37.0")) {
BEEPER_CONFIG.dshotBeaconTone = data.readU8();
}
break;
case MSPCodes.MSP_BOARD_ALIGNMENT_CONFIG:
@ -1200,6 +1204,9 @@ MspHelper.prototype.crunch = function(code) {
case MSPCodes.MSP_SET_BEEPER_CONFIG:
var beeperMask = BEEPER_CONFIG.beepers.getMask();
buffer.push32(beeperMask);
if (semver.gte(CONFIG.apiVersion, "1.37.0")) {
buffer.push8(BEEPER_CONFIG.dshotBeaconTone );
}
break;
case MSPCodes.MSP_SET_MIXER_CONFIG:
buffer.push8(MIXER_CONFIG.mixer)
@ -1525,12 +1532,21 @@ MspHelper.prototype.crunch = function(code) {
break;
case MSPCodes.MSP_ARMING_DISABLE:
var value;
if (CONFIG.arming_disabled) {
if (CONFIG.armingDisabled) {
value = 1;
} else {
value = 0;
}
buffer.push8(value);
if (CONFIG.runawayTakeoffPreventionDisabled) {
value = 1;
} else {
value = 0;
}
// This will be ignored if `armingDisabled` is true
buffer.push8(value);
break;
default:
return false;
@ -2022,13 +2038,19 @@ MspHelper.prototype.sendRxFailConfig = function(onCompleteCallback) {
}
}
MspHelper.prototype.setArmingEnabled = function(doEnable, onCompleteCallback) {
if (semver.gte(CONFIG.apiVersion, "1.37.0") && (doEnable === CONFIG.arming_disabled)) {
CONFIG.arming_disabled = !doEnable;
MspHelper.prototype.setArmingEnabled = function(doEnable, disableRunawayTakeoffPrevention, onCompleteCallback) {
if (semver.gte(CONFIG.apiVersion, "1.37.0") && (CONFIG.armingDisabled === doEnable || CONFIG.runawayTakeoffPreventionDisabled !== disableRunawayTakeoffPrevention)) {
CONFIG.armingDisabled = !doEnable;
CONFIG.runawayTakeoffPreventionDisabled = disableRunawayTakeoffPrevention;
MSP.send_message(MSPCodes.MSP_ARMING_DISABLE, mspHelper.crunch(MSPCodes.MSP_ARMING_DISABLE), false, function () {
if (doEnable) {
GUI.log(i18n.getMessage('armingEnabled'));
if (disableRunawayTakeoffPrevention) {
GUI.log(i18n.getMessage('runawayTakeoffPreventionDisabled'));
} else {
GUI.log(i18n.getMessage('runawayTakeoffPreventionEnabled'));
}
} else {
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 'device_lost':
CONFIG.arming_disabled = false;
CONFIG.armingDisabled = false;
CONFIG.runawayTakeoffPreventionDisabled = false;
if (GUI.connected_to || GUI.connecting_to) {
$('a.connect').click();

View File

@ -72,7 +72,7 @@ function initializeSerialBackend() {
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 () {
GUI.log(i18n.getMessage('craftNameReceived', [CONFIG.name]));
CONFIG.arming_disabled = false;
mspHelper.setArmingEnabled(false, finishOpen);
CONFIG.armingDisabled = false;
mspHelper.setArmingEnabled(false, false, finishOpen);
});
} else {
finishOpen();

View File

@ -235,7 +235,38 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
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 destination = $('.beepers .beeper-configuration');
var beeper_e = $('.tab-configuration .beepers');
@ -545,7 +576,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
}
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")) {
@ -585,7 +616,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
spiRxTypes.push(
'FRSKY_X',
'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) {
$('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 {
$('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 .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').find('a').each(function() {
$(this).attr('target', '_blank');
});
$('div.release_info').slideDown();

View File

@ -230,6 +230,11 @@ TABS.motors.initialize = function (callback) {
accel_offset = [0, 0, 0],
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 = {
x: [],
@ -310,7 +315,7 @@ TABS.motors.initialize = function (callback) {
var rate = parseInt($('.tab-motors select[name="rate"]').val(), 10);
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) {
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 () {
gyro_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');
mspHelper.setArmingEnabled(enabled);
mspHelper.setArmingEnabled(enabled, enabled);
}).change();
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)
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")) {
loggingRates = [

View File

@ -1,6 +1,7 @@
'use strict';
var SYM = SYM || {};
SYM.BLANK = 0x20;
SYM.VOLT = 0x06;
SYM.RSSI = 0x01;
SYM.AH_RIGHT = 0x02;
@ -587,6 +588,7 @@ OSD.constants = {
name: 'MAIN_BATT_VOLTAGE',
desc: 'osdDescElementMainBattVoltage',
default_position: -29,
draw_order: 20,
positionable: true,
preview: FONT.symbol(SYM.BATTERY) + '16.8' + FONT.symbol(SYM.VOLT)
},
@ -594,6 +596,7 @@ OSD.constants = {
name: 'RSSI_VALUE',
desc: 'osdDescElementRssiValue',
default_position: -59,
draw_order: 30,
positionable: true,
preview: FONT.symbol(SYM.RSSI) + '99'
},
@ -607,6 +610,7 @@ OSD.constants = {
name: 'THROTTLE_POSITION',
desc: 'osdDescElementThrottlePosition',
default_position: -9,
draw_order: 110,
positionable: true,
preview: FONT.symbol(SYM.THR) + FONT.symbol(SYM.THR1) + '69'
},
@ -619,6 +623,7 @@ OSD.constants = {
VTX_CHANNEL: {
name: 'VTX_CHANNEL',
default_position: 1,
draw_order: 120,
positionable: true,
preview: 'R:2:1'
},
@ -639,31 +644,88 @@ OSD.constants = {
name: 'DISARMED',
desc: 'osdDescElementDisarmed',
default_position: -109,
draw_order: 280,
positionable: true,
preview: 'DISARMED'
},
CROSSHAIRS: {
name: 'CROSSHAIRS',
desc: 'osdDescElementCrosshairs',
default_position: -1,
positionable: false
default_position: 193,
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: {
name: 'ARTIFICIAL_HORIZON',
desc: 'osdDescElementArtificialHorizon',
default_position: -1,
positionable: false
default_position: 194,
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: {
name: 'HORIZON_SIDEBARS',
desc: 'osdDescElementHorizonSidebars',
default_position: -1,
positionable: false
default_position: 194,
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: {
name: 'CURRENT_DRAW',
desc: 'osdDescElementCurrentDraw',
default_position: -23,
draw_order: 130,
positionable: true,
preview: function() {
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',
desc: 'osdDescElementMahDrawn',
default_position: -18,
draw_order: 140,
positionable: true,
preview: function() {
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',
desc: 'osdDescElementCraftName',
default_position: -77,
draw_order: 150,
positionable: true,
preview: function(osd_data) {
return OSD.generateCraftName(osd_data, 1);
@ -691,6 +755,7 @@ OSD.constants = {
name: 'ALTITUDE',
desc: 'osdDescElementAltitude',
default_position: 62,
draw_order: 160,
positionable: true,
preview: function(osd_data) {
return '399.7' + FONT.symbol(osd_data.unit_mode === 0 ? SYM.FEET : SYM.METRE)
@ -714,6 +779,7 @@ OSD.constants = {
name: 'FLYMODE',
desc: 'osdDescElementFlyMode',
default_position: -1,
draw_order: 90,
positionable: true,
preview: 'STAB'
},
@ -721,6 +787,7 @@ OSD.constants = {
name: 'GPS_SPEED',
desc: 'osdDescElementGPSSpeed',
default_position: -1,
draw_order: 330,
positionable: true,
preview: ' 40K'
},
@ -728,6 +795,7 @@ OSD.constants = {
name: 'GPS_SATS',
desc: 'osdDescElementGPSSats',
default_position: -1,
draw_order: 320,
positionable: true,
preview: FONT.symbol(SYM.GPS_SAT_L) + FONT.symbol(SYM.GPS_SAT_R) + '14'
},
@ -735,6 +803,7 @@ OSD.constants = {
name: 'GPS_LON',
desc: 'osdDescElementGPSLon',
default_position: -1,
draw_order: 350,
positionable: true,
preview: FONT.symbol(SYM.ARROW_SOUTH) + '00.00000000'
},
@ -742,6 +811,7 @@ OSD.constants = {
name: 'GPS_LAT',
desc: 'osdDescElementGPSLat',
default_position: -1,
draw_order: 340,
positionable: true,
preview: FONT.symbol(SYM.ARROW_EAST) + '00.00000000'
},
@ -749,6 +819,7 @@ OSD.constants = {
name: 'DEBUG',
desc: 'osdDescElementDebug',
default_position: -1,
draw_order: 240,
positionable: true,
preview: 'DBG 0 0 0 0'
},
@ -756,6 +827,7 @@ OSD.constants = {
name: 'PID_ROLL',
desc: 'osdDescElementPIDRoll',
default_position: 0x800 | (10 << 5) | 2, // 0x0800 | (y << 5) | x
draw_order: 170,
positionable: true,
preview: 'ROL 43 40 20'
},
@ -763,6 +835,7 @@ OSD.constants = {
name: 'PID_PITCH',
desc: 'osdDescElementPIDPitch',
default_position: 0x800 | (11 << 5) | 2, // 0x0800 | (y << 5) | x
draw_order: 180,
positionable: true,
preview: 'PIT 58 50 22'
},
@ -770,6 +843,7 @@ OSD.constants = {
name: 'PID_YAW',
desc: 'osdDescElementPIDYaw',
default_position: 0x800 | (12 << 5) | 2, // 0x0800 | (y << 5) | x
draw_order: 190,
positionable: true,
preview: 'YAW 70 45 20'
},
@ -777,6 +851,7 @@ OSD.constants = {
name: 'POWER',
desc: 'osdDescElementPower',
default_position: (15 << 5) | 2,
draw_order: 200,
positionable: true,
preview: function() {
return semver.gte(CONFIG.apiVersion, "1.36.0") ? ' 142W' : '142W';
@ -786,13 +861,14 @@ OSD.constants = {
name: 'PID_RATE_PROFILE',
desc: 'osdDescElementPIDRateProfile',
default_position: 0x800 | (13 << 5) | 2, // 0x0800 | (y << 5) | x
draw_order: 210,
positionable: true,
preview: '1-2'
},
BATTERY_WARNING: {
name: 'BATTERY_WARNING',
desc: 'osdDescElementBatteryWarning',
default_position: -1,
default_position: -1,
positionable: true,
preview: 'LOW VOLTAGE'
},
@ -800,6 +876,7 @@ OSD.constants = {
name: 'AVG_CELL_VOLTAGE',
desc: 'osdDescElementAvgCellVoltage',
default_position: 12 << 5,
draw_order: 230,
positionable: true,
preview: FONT.symbol(SYM.BATTERY) + '3.98' + FONT.symbol(SYM.VOLT)
},
@ -807,6 +884,7 @@ OSD.constants = {
name: 'PITCH_ANGLE',
desc: 'osdDescElementPitchAngle',
default_position: -1,
draw_order: 250,
positionable: true,
preview: '-00.0'
},
@ -814,6 +892,7 @@ OSD.constants = {
name: 'ROLL_ANGLE',
desc: 'osdDescElementRollAngle',
default_position: -1,
draw_order: 260,
positionable: true,
preview: '-00.0'
},
@ -821,6 +900,7 @@ OSD.constants = {
name: 'MAIN_BATT_USAGE',
desc: 'osdDescElementMainBattUsage',
default_position: -17,
draw_order: 270,
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)
},
@ -835,6 +915,7 @@ OSD.constants = {
name: 'HOME_DIRECTION',
desc: 'osdDescElementHomeDirection',
default_position: -1,
draw_order: 370,
positionable: true,
preview: FONT.symbol(SYM.ARROW_SOUTH + 2)
},
@ -842,6 +923,7 @@ OSD.constants = {
name: 'HOME_DISTANCE',
desc: 'osdDescElementHomeDistance',
default_position: -1,
draw_order: 360,
positionable: true,
preview: function(osd_data) {
return '43' + FONT.symbol(osd_data.unit_mode === 0 ? SYM.FEET : SYM.METRE)
@ -851,6 +933,7 @@ OSD.constants = {
name: 'NUMERICAL_HEADING',
desc: 'osdDescElementNumericalHeading',
default_position: -1,
draw_order: 290,
positionable: true,
preview: FONT.symbol(SYM.ARROW_EAST) + '90'
},
@ -858,6 +941,7 @@ OSD.constants = {
name: 'NUMERICAL_VARIO',
desc: 'osdDescElementNumericalVario',
default_position: -1,
draw_order: 300,
positionable: true,
preview: FONT.symbol(SYM.ARROW_NORTH) + '8.7'
},
@ -865,6 +949,7 @@ OSD.constants = {
name: 'COMPASS_BAR',
desc: 'osdDescElementCompassBar',
default_position: -1,
draw_order: 310,
positionable: true,
preview: function(osd_data) {
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',
desc: 'osdDescElementWarnings',
default_position: -1,
draw_order: 220,
positionable: true,
preview: 'LOW VOLTAGE'
},
@ -883,6 +969,7 @@ OSD.constants = {
name: 'ESC_TEMPERATURE',
desc: 'osdDescElementEscTemperature',
default_position: -1,
draw_order: 380,
positionable: true,
preview: FONT.symbol(SYM.TEMP_C) + '45'
},
@ -890,6 +977,7 @@ OSD.constants = {
name: 'ESC_RPM',
desc: 'osdDescElementEscRpm',
default_position: -1,
draw_order: 390,
positionable: true,
preview: '226000'
},
@ -897,6 +985,7 @@ OSD.constants = {
name: 'REMAINING_TIME_ESTIMATE',
desc: 'osdDescElementRemaningTimeEstimate',
default_position: -1,
draw_order: 80,
positionable: true,
preview: '01:13'
},
@ -904,6 +993,7 @@ OSD.constants = {
name: 'RTC_DATE_TIME',
desc: 'osdDescElementRtcDateTime',
default_position: -1,
draw_order: 400,
positionable: true,
preview: '2017-11-11 16:20:00'
},
@ -911,6 +1001,7 @@ OSD.constants = {
name: 'ADJUSTMENT_RANGE',
desc: 'osdDescElementAdjustmentRange',
default_position: -1,
draw_order: 410,
positionable: true,
preview: 'PITCH/ROLL P: 42'
},
@ -918,6 +1009,7 @@ OSD.constants = {
name: 'TIMER_1',
desc: 'osdDescElementTimer1',
default_position: -1,
draw_order: 60,
positionable: true,
preview: function(osd_data) {
return OSD.generateTimerPreview(osd_data, 0);
@ -927,6 +1019,7 @@ OSD.constants = {
name: 'TIMER_2',
desc: 'osdDescElementTimer2',
default_position: -1,
draw_order: 70,
positionable: true,
preview: function(osd_data) {
return OSD.generateTimerPreview(osd_data, 1);
@ -936,6 +1029,7 @@ OSD.constants = {
name: 'CORE_TEMPERATURE',
desc: 'osdDescElementCoreTemperature',
default_position: -1,
draw_order: 420,
positionable: true,
preview: function(osd_data) {
return OSD.generateTemperaturePreview(osd_data, 33);
@ -1009,6 +1103,10 @@ OSD.constants = {
RTC_DATE_TIME: {
name: 'RTC_DATE_TIME',
desc: 'osdDescStatRtcDateTime'
},
STAT_BATTERY: {
name: 'STAT_BATTERY',
desc: 'osdDescStatBattery'
}
},
ALL_WARNINGS: {
@ -1035,7 +1133,12 @@ OSD.constants = {
CRASH_FLIP_MODE: {
name: 'CRASH_FLIP_MODE',
desc: 'osdWarningCrashFlipMode'
},
ESC_FAIL: {
name: 'OSD_WARNING_ESC_FAIL',
desc: 'osdWarningEscFail'
}
},
FONT_TYPES: [
{ 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
OSD.chooseFields = function () {
var F = OSD.constants.ALL_DISPLAY_FIELDS;
@ -1176,6 +1293,11 @@ OSD.chooseFields = function () {
OSD.constants.STATISTIC_FIELDS = OSD.constants.STATISTIC_FIELDS.concat([
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
@ -1189,6 +1311,11 @@ OSD.chooseFields = function () {
F.VISUAL_BEEPER,
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() {
@ -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 = {
/**
@ -1363,6 +1508,7 @@ OSD.msp = {
name: suffix ? c.name + suffix : c.name,
desc: c.desc,
index: j,
draw_order: c.draw_order,
positionable: c.positionable,
preview: suffix ? c.preview + suffix : c.preview
}, 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) {
if (typeof(item.preview) === 'function') {
item.preview = item.preview(d);
}
if (typeof(item.positionable) === 'function') {
item.positionable = item.positionable(d);
}
}
OSD.updateDisplaySize();
@ -1440,8 +1589,18 @@ OSD.GUI.preview = {
},
onDragStart: function(e) {
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.setDragImage($(this).data('field').preview_img, 6, 9);
ev.dataTransfer.setDragImage($(this).data('field').preview_img, offsetX, offsetY);
},
onDragOver: function(e) {
var ev = e.originalEvent;
@ -1460,10 +1619,35 @@ OSD.GUI.preview = {
var position = $(this).removeAttr('style').data('position');
var field_id = parseInt(ev.dataTransfer.getData('text/plain'))
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) {
position += overflows_line;
var overflows_line = 0;
// 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")) {
// unsigned now
} else {
@ -1846,53 +2030,75 @@ TABS.osd.initialize = function (callback) {
OSD.data.preview[i * 30 + j] = [{name: 'LOGO', positionable: false}, x++];
}
}
// draw all the displayed items and the drag and drop preview images
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
field.preview_img = new Image();
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
// fill the screen buffer
for(var i = 0; i < field.preview.length; i++) {
var charCode = field.preview.charCodeAt(i);
OSD.data.preview[j++] = [field, charCode];
// draw the preview
var img = new Image();
img.src = FONT.draw(charCode);
ctx.drawImage(img, i*12, 0);
// Standard preview, type String
if (field.preview.constructor !== Array) {
// fill the screen buffer
for(var i = 0; i < field.preview.length; i++) {
// 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');
// Required for NW.js - Otherwise the <img /> will
// consume drag/drop events.
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;
// Required for NW.js - Otherwise the <img /> will
//consume drag/drop events.
field.preview_img.style.pointerEvents = 'none';
}
// render
var $preview = $('.display-layout .preview').empty();
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="dTermNotchCutoff"]').val(FILTER_CONFIG.dterm_notch_cutoff);
$('input[name="dtermSetpointTransition-number"]').val(ADVANCED_TUNING.dtermSetpointTransition / 100);
$('input[name="dtermSetpointTransition-range"]').val(ADVANCED_TUNING.dtermSetpointTransition / 100);
var dtermSetpointTransitionNumberElement = $('input[name="dtermSetpointTransition-number"]');
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-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 });
}
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++) {
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?
channelMSPIndexes = {
roll: 0,
pitch: 1,
throttle: 2,
yaw: 3,
aux1: 4,
aux2: 5,
aux3: 6,
aux4: 7,
Roll: 0,
Pitch: 1,
Throttle: 2,
Yaw: 3,
Aux1: 4,
Aux2: 5,
Aux3: 6,
Aux4: 7,
},
// Set reasonable initial stick positions (Mode 2)
stickValues = {
throttle: CHANNEL_MIN_VALUE,
pitch: CHANNEL_MID_VALUE,
roll: CHANNEL_MID_VALUE,
yaw: CHANNEL_MID_VALUE,
aux1: CHANNEL_MIN_VALUE,
aux2: CHANNEL_MIN_VALUE,
aux3: CHANNEL_MIN_VALUE,
aux4: CHANNEL_MIN_VALUE
Throttle: CHANNEL_MIN_VALUE,
Pitch: CHANNEL_MID_VALUE,
Roll: CHANNEL_MID_VALUE,
Yaw: CHANNEL_MID_VALUE,
Aux1: CHANNEL_MIN_VALUE,
Aux2: CHANNEL_MIN_VALUE,
Aux3: CHANNEL_MIN_VALUE,
Aux4: CHANNEL_MIN_VALUE
},
// First the vertical axis, then the horizontal:
gimbals = [
["throttle", "yaw"],
["pitch", "roll"],
["Throttle", "Yaw"],
["Pitch", "Roll"],
],
gimbalElems,
@ -40,6 +40,18 @@ var
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() {
var
channelValues = [0, 0, 0, 0, 0, 0, 0, 0];
@ -148,7 +160,7 @@ $(document).ready(function() {
$(".slider", sliderElems).each(function(sliderIndex) {
var
initialValue = stickValues["aux" + (sliderIndex + 1)];
initialValue = stickValues["Aux" + (sliderIndex + 1)];
$(this)
.noUiSlider({
@ -160,7 +172,7 @@ $(document).ready(function() {
}).on('slide change set', function(e, value) {
value = Math.round(parseFloat(value));
stickValues["aux" + (sliderIndex + 1)] = value;
stickValues["Aux" + (sliderIndex + 1)] = value;
$(".tooltip", this).text(value);
});

View File

@ -37,6 +37,7 @@
<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-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/jquery-2.1.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 class="header-wrapper">
<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">
<li class="dataflash-free_global">
<div class="legend">Dataflash: free space</div>
<div class="legend" i18n="sensorDataFlashFreeSpace"></div>
</li>
</ul>
<div id="expertMode" align="center">
@ -171,22 +172,22 @@
<div id="sensor-status" class="sensor_state mode-connected">
<ul>
<li class="gyro" i18n_title="sensorStatusGyro">
<div class="gyroicon">Gyro</div>
<div class="gyroicon" i18n="sensorStatusGyroShort"></div>
</li>
<li class="accel" i18n_title="sensorStatusAccel">
<div class="accicon">Accel</div>
<div class="accicon" i18n="sensorStatusAccelShort"></div>
</li>
<li class="mag" i18n_title="sensorStatusMag">
<div class="magicon">Mag</div>
<div class="magicon" i18n="sensorStatusMagShort"></div>
</li>
<li class="baro" i18n_title="sensorStatusBaro">
<div class="baroicon">Baro</div>
<div class="baroicon" i18n="sensorStatusBaroShort"></div>
</li>
<li class="gps" i18n_title="sensorStatusGPS">
<div class="gpsicon">GPS</div>
<div class="gpsicon" i18n="sensorStatusGPSShort"></div>
</li>
<li class="sonar" i18n_title="sensorStatusSonar">
<div class="sonaricon">Sonar</div>
<div class="sonaricon" i18n="sensorStatusSonarShort"></div>
</li>
</ul>
</div>
@ -208,7 +209,7 @@
<div class="clear-both"></div>
<div id="log">
<div class="logswitch">
<a href="#" id="showlog">Show Log</a>
<a href="#" id="showlog" i18n="logActionShow"></a>
</div>
<div id="scrollicon"></div>
<div class="wrapper"></div>

View File

@ -674,9 +674,56 @@
</td>
</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">
<td style="width:calc(100%)" colspan="2">
<!-- ROW 4 - FULL WIDTH PANE -->
<!-- ROW 6 - FULL WIDTH PANE -->
<!-- BEEPER -->
<div class="beepers" style="width: calc(100%);">

View File

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

View File

@ -9,7 +9,7 @@
<div class="content_mid">
<div class="column third_left text1">
<div class="wrap">
<h2>Hardware</h2>
<h2 i18n="defaultWelcomeHead"></h2>
<div i18n="defaultWelcomeText"></div>
</div>
</div>
@ -24,7 +24,7 @@
<h3 i18n="defaultDonateHead"></h3>
<div i18n="defaultDonateText"></div>
<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"
height="30" /></a>
</li>

View File

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

View File

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

View File

@ -99,6 +99,13 @@
</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 class="gui_box motorblock">

View File

@ -294,8 +294,8 @@
</td>
</tr>
<tr class="dtermSetpoint" style="height:30px;">
<td><input type="number" name="dtermSetpoint-number" 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.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.54"/></td>
<td>
<div>
<label>

View File

@ -201,7 +201,7 @@
</label>
</div>
<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>
</label>
</div>

View File

@ -1,16 +1,16 @@
<html>
<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-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="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.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>
<body>
<div class="control-gimbals">
@ -49,16 +49,9 @@
</div>
</div>
<div class="warning">
<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>
<p i18n="receiverMspWarningText"></p>
<div class="button-enable btn">
<a class="button-enable" href="#">Enable controls</a>
<a class="button-enable" href="#" i18n="receiverMspEnableButton"></a>
</div>
</div>
</body>