Merge branch 'master' into dzikuvx-wizard
|
@ -175,13 +175,13 @@ https://hub.docker.com/r/yagajs/mapproxy/ Docker image (untested)
|
||||||
base: GLOBAL_MERCATOR
|
base: GLOBAL_MERCATOR
|
||||||
origin: ul
|
origin: ul
|
||||||
```
|
```
|
||||||
1. You can use any map provider that is compatible with MapProxy, and once you zoom in on the region you will be flying in, the map tiles will be cached for offline use. You can test this by disabling your internet connection and browsing the demo url in a browser
|
1. You can use any map provider that is compatible with MapProxy, and once you zoom in on the region you will be flying in, the map tiles will be cached for offline use. You can test this by disabling your internet connection and browsing the demo URL in a browser
|
||||||
|
|
||||||
https://wiki.openstreetmap.org/wiki/WMS#OSM_WMS_Servers OpenStreetMap WSM servers
|
https://wiki.openstreetmap.org/wiki/WMS#OSM_WMS_Servers OpenStreetMap WSM servers
|
||||||
|
|
||||||
https://lpdaac.usgs.gov/data_access/web_map_services_wms # USGS currently has 400+ WMS layers
|
https://lpdaac.usgs.gov/data_access/web_map_services_wms # USGS currently has 400+ WMS layers
|
||||||
|
|
||||||
* You can use QGIS to browse different provieders and pick the maps you like for your iNav layers
|
* You can use QGIS to browse different providers and pick the maps you like for your iNav layers
|
||||||
https://qgis.org/en/site/
|
https://qgis.org/en/site/
|
||||||
|
|
||||||
* There are many government and public wms providers available in different regions worldwide
|
* There are many government and public WMS providers available in different regions worldwide
|
||||||
|
|
120
README.md
|
@ -1,88 +1,121 @@
|
||||||
# INAV Configurator
|
# INAV Configurator
|
||||||
|
|
||||||
INAV Configurator is a crossplatform configuration tool for the [INAV](https://github.com/iNavFlight/inav) flight control system.
|
INAV Configurator is a cross-platform configuration tool for the [INAV](https://github.com/iNavFlight/inav) flight control system.
|
||||||
|
|
||||||
It runs as an app within Google Chrome and allows you to configure the INAV software running on any supported INAV target.
|
It runs as an app within Google Chrome and allows you to configure the INAV software running on any supported INAV target.
|
||||||
|
|
||||||
Various types of aircraft are supported by the tool and by INAV, e.g. quadcopters, hexacopters, octocopters and fixed-wing aircraft.
|
Various types of aircraft are supported by the tool and by INAV, e.g. quadcopters, hexacopters, octocopters, and fixed-wing aircraft.
|
||||||
|
|
||||||
# Support
|
# Support
|
||||||
|
|
||||||
INAV Configurator comes `as is`, without any warranty and support from authors. If you found a bug, please create an issue on [GitHub](https://github.com/iNavFlight/inav-configurator/issues).
|
INAV Configurator comes `as is`, without any warranty and support from the authors. If you find a bug, please create an issue on [GitHub](https://github.com/iNavFlight/inav-configurator/issues).
|
||||||
|
|
||||||
GitHub issue tracker is reserved for bugs and other technical problems. If you do not know how to setup
|
The GitHub issue tracker is reserved for bugs and other technical problems. If you do not know how to set up
|
||||||
everything, hardware is not working or have any other _support_ problem, please consult:
|
everything, the hardware is not working, or you have any other _support_ problem, please consult:
|
||||||
|
|
||||||
* [INAV Discord Server](https://discord.gg/peg2hhbYwN)
|
* [INAV Discord Server](https://discord.gg/peg2hhbYwN)
|
||||||
* [INAV Official on Facebook](https://www.facebook.com/groups/INAVOfficial)
|
* [INAV Official on Facebook](https://www.facebook.com/groups/INAVOfficial)
|
||||||
* [RC Groups Support](https://www.rcgroups.com/forums/showthread.php?2495732-Cleanflight-iNav-(navigation-rewrite)-project)
|
* [RC Groups Support](https://www.rcgroups.com/forums/showthread.php?2495732-Cleanflight-iNav-(navigation-rewrite)-project)
|
||||||
* [INAV Official on Telegram](https://t.me/INAVFlight)
|
* [INAV Official on Telegram](https://t.me/INAVFlight)
|
||||||
|
|
||||||
## INAV Configurator start minimized, what should I do?
|
## INAV Configurator starts minimized, what should I do?
|
||||||
|
|
||||||
You have to remove `C:\Users%Your_UserNname%\AppData\Local\inav-configurator` folder and all its content.
|
You have to remove the `C:\Users%Your_UserName%\AppData\Local\inav-configurator` folder and all its content.
|
||||||
|
|
||||||
[https://www.youtube.com/watch?v=XMoULyiFDp4](https://www.youtube.com/watch?v=XMoULyiFDp4)
|
[https://www.youtube.com/watch?v=XMoULyiFDp4](https://www.youtube.com/watch?v=XMoULyiFDp4)
|
||||||
|
|
||||||
Alternatively, on Windows with PowerShell you can use `post_install_cleanup.ps1` script that will do the cleaning. (thank you James Cherrill)
|
Alternatively, on Windows with PowerShell, you can use the `post_install_cleanup.ps1` script that will do the cleaning. (thank you, James Cherrill)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Depending on target operating system, _INAV Configurator_ is distributed as _standalone_ application or Chrome App.
|
Depending on the target operating system, _INAV Configurator_ is distributed as a _standalone_ application or Chrome App.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
||||||
1. Download Configurator for Windows platform (win32 or win64 is present)
|
1. Download Configurator for Windows platform (win32 or win64 is present)
|
||||||
1. Extract ZIP archive
|
1. Extract ZIP archive
|
||||||
1. Run INAV Configurator app from unpacked folder
|
1. Run the INAV Configurator app from the unpacked folder
|
||||||
1. Configurator is not signed, so you have to allow Windows to run untrusted application. There might be a monit for it during first run
|
1. Configurator is not signed, so you have to allow Windows to run untrusted applications. There might be a monit for it during the first run
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
||||||
1. Download Configurator for Linux platform (linux32 and linux64 are present)
|
2. Download Configurator for Linux platform (linux32 and linux64 are present)
|
||||||
1. Extract tar.gz archive
|
* **.rpm** is the Fedora installation file. Just download and install using `sudo dnf localinstall /path/to/INAV-Configurator_linux64-x.y.z-x86_64.rpm` or open it with a package manager (e.g. via Files)
|
||||||
1. Make the following files executable:
|
* **.deb** is the Debian/Ubuntu installation file. Just download and install using `sudo apt install /path/to/INAV-Configurator_linux64_x.y.z.deb` or open it with a package manager (e.g. via the File Manager)
|
||||||
* inav-configurator `chmod +x inav-configurator`
|
* **.tar.gz** is a universal archive. Download and continue with these instructions to install
|
||||||
* (5.0.0+) chrome_crashpad_handler `chmod +x chrome_crashpad_handler`
|
3. Change to the directory containing the downloaded **tar.gz** file
|
||||||
1. Run INAV Configurator app from unpacked folder
|
4. download [this](https://raw.githubusercontent.com/iNavFlight/inav-configurator/master/assets/linux/inav-configurator.desktop) file to the same directory. Its filename should be `inav-configurator.desktop`.
|
||||||
|
5. Extract **tar.gz** archive
|
||||||
|
```
|
||||||
|
tar -C /tmp/ -xf INAV-Configurator_linuxNN_x.y.z.tar.gz
|
||||||
|
```
|
||||||
|
**NN** is the bits of your OS. **x.y.z** is the INAV Configurator version number.
|
||||||
|
|
||||||
On some Linux distros, you may be missing `libatomic`, a `NW.JS` (specially `libnode.so`) dependency. If so, please install `libatomic` using your distro's package manager, e.g:
|
6. If this is the first time installing INAV Configurator, create a home for its files
|
||||||
|
```
|
||||||
|
sudo mkdir /opt/inav
|
||||||
|
sudo chown $USER /opt/inav
|
||||||
|
```
|
||||||
|
7. Move the temporary files into their home
|
||||||
|
```
|
||||||
|
mv /tmp/INAV\ Configurator /opt/inav/inav-configurator
|
||||||
|
```
|
||||||
|
8. Update the application icon.
|
||||||
|
```
|
||||||
|
sudo mkdir /opt/inav/inav-configurator/icon
|
||||||
|
sudo cp /opt/inav/inav-configurator/images/inav_icon_128.png /opt/inav/inav-configurator/icon
|
||||||
|
```
|
||||||
|
9. As a one-off, move the desktop file into the applications directory
|
||||||
|
```
|
||||||
|
sudo mv inav-configurator.desktop /usr/share/applications/
|
||||||
|
```
|
||||||
|
10. Make the following files executable:
|
||||||
|
* inav-configurator `chmod +x /opt/inav/inav-configurator/inav-configurator`
|
||||||
|
* (5.0.0+) chrome_crashpad_handler `chmod +x /opt/inav/inav-configurator/chrome_crashpad_handler`
|
||||||
|
11. Run the INAV Configurator app from the unpacked folder `/opt/inav/inav-configurator/inav-configurator`
|
||||||
|
|
||||||
|
#### Notes
|
||||||
|
|
||||||
|
On some Linux distros, you may be missing `libatomic` and/or `NW.JS` (especially `libnode.so`) dependencies. If so, please install `libatomic` using your distro's package manager, e.g:
|
||||||
|
|
||||||
* Arch Linux: `sudo pacman -S --needed libatomic_ops`
|
* Arch Linux: `sudo pacman -S --needed libatomic_ops`
|
||||||
* Debian / Ubuntu: `sudo apt install libatomic1`
|
* Debian / Ubuntu: `sudo apt install libatomic1`
|
||||||
* Fedora: `sudo dnf install libatomic`
|
* Fedora: `sudo dnf install libatomic`
|
||||||
|
|
||||||
|
1. Don't forget to add your user to the dialout group "sudo usermod -aG dialout YOUR_USERNAME" for serial access
|
||||||
|
2. If you have 3D model animation problems, enable "Override software rendering list" in Chrome flags chrome://flags/#ignore-gpu-blacklist
|
||||||
|
|
||||||
### Mac
|
### Mac
|
||||||
|
|
||||||
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
||||||
1. Download Configurator for Mac platform
|
1. Download Configurator for the Mac platform
|
||||||
1. Extract ZIP archive
|
1. Extract ZIP archive
|
||||||
1. Run INAV Configurator
|
1. Run INAV Configurator
|
||||||
1. Configurator is not signed, so you have to allow Mac to run untrusted application. There might be a monit for it during first run
|
|
||||||
|
|
||||||
## Building and running INAV Configurator locally (for development or Linux users)
|
## Building and running INAV Configurator locally (for development)
|
||||||
|
|
||||||
For local development, **node.js** build system is used.
|
For local development, the **node.js** build system is used.
|
||||||
|
|
||||||
1. Install node.js
|
1. Install node.js
|
||||||
1. From project folder run `npm install`
|
1. From the project folder run `npm install`
|
||||||
1. To build the JS and CSS files and start the configurator:
|
1. To build the JS and CSS files and start the configurator:
|
||||||
- With NW.js: Run `npm start`.
|
- With NW.js: Run `npm start`.
|
||||||
- With Chrome: Run `npm run gulp`. Then open `chrome://extensions`, enable
|
- With Chrome: Run `npm run gulp`. Then open `chrome://extensions`, enable
|
||||||
the `Developer mode`, click on the `Load unpacked extension...` button and select the `inav-configurator` directory.
|
the `Developer mode`, click on the `Load unpacked extension...` button, and select the `inav-configurator` directory.
|
||||||
|
|
||||||
Other tasks are also defined in `gulpfile.js`. To run a task, use `node ./node_modules/gulp/bin/gulp.js task-name`. Available ones are:
|
Other tasks are also defined in `gulpfile.js`. To run a task, use `node ./node_modules/gulp/bin/gulp.js task-name`. Available ones are:
|
||||||
|
|
||||||
- **build**: Generate JS and CSS output files used by the configurator from their sources. It must be run whenever changes are made to any `.js` or `.css` files in order to have those changes appear
|
- **build**: Generate JS and CSS output files used by the configurator from their sources. It must be run whenever changes are made to any `.js` or `.css` files in order to have those changes appear
|
||||||
in the configurator. If new files are added, they must be included in `gulpfile.js`. See the comments at the top of `gulpfile.js` to learn how to do so. See also the `watch` task.
|
in the configurator. If new files are added, they must be included in `gulpfile.js`. See the comments at the top of `gulpfile.js` to learn how to do so. See also the `watch` task.
|
||||||
- **watch**: Watch JS and CSS sources for changes and run the `build` task whenever they're edited.
|
- **watch**: Watch JS and CSS sources for changes and run the `build` task whenever they're edited.
|
||||||
- **dist**: Create a distribution of the app (valid for packaging both as a Chrome app or a NW.js app)
|
- **dist**: Create a distribution of the app (valid for packaging both as a Chrome app or NW.js app)
|
||||||
in the `./dist/` directory.
|
in the `./dist/` directory.
|
||||||
- **release**: Create NW.js apps for each supported platform (win32, osx64 and linux64) in the `./apps`
|
- **release**: Create NW.js apps for each supported platform (win32, osx64 and linux64) in the `./apps`
|
||||||
directory. Running this task on macOS or Linux requires Wine, since it's needed to set the icon
|
directory. Running this task on macOS or Linux requires Wine since it's needed to set the icon
|
||||||
for the Windows app. If you don't have Wine installed you can create a release by running the **release-only-linux** task.
|
for the Windows app. If you don't have Wine installed, you can create a release by running the **release-only-Linux** task.
|
||||||
|
<br>`--installer` argument can be added to build installers for a particular OS. NOTE: MacOS Installer can be built with MacOS only.
|
||||||
|
|
||||||
To build a specific release, use the command `release --platform="win64"` for example.
|
To build a specific release, use the command `release --platform="win64"` for example.
|
||||||
|
|
||||||
|
@ -94,17 +127,17 @@ To be able to open Inspector, you will need SDK flavours of NW.js
|
||||||
|
|
||||||
## Different map providers
|
## Different map providers
|
||||||
|
|
||||||
INAV Configurator 2.1 allows to choose between OpenStreetMap, Bing Maps, and MapProxy map providers.
|
INAV Configurator 2.1 allows you to choose between OpenStreetMap, Bing Maps (Aerial View), and MapProxy map providers.
|
||||||
INAV Configurator is shipped **WITHOUT** API key for Bing Maps. That means: every user who wants to use Bing Maps has to create own account, agree to all _Terms and Conditions_ required by Bing Maps and configure INAV Configuerator by himself.
|
INAV Configurator is shipped **WITHOUT** API key for Bing Maps. That means: every user who wants to use Bing Maps has to create their own account, agree to all _Terms and Conditions_ required by Bing Maps, and configure INAV Configurator by himself.
|
||||||
|
|
||||||
### How to choose Map provider
|
### How to choose a Map provider
|
||||||
|
|
||||||
1. Click **Settings** icon in the top-right corner of INAV Configurator
|
1. Click **Settings** icon in the top-right corner of INAV Configurator
|
||||||
1. Choose provider: OpenStreetMap, Bing, or MapProxy
|
1. Choose a provider: OpenStreetMap, Bing, or MapProxy
|
||||||
1. In the case of Bing Maps, you have to provide your own, personal, generated by you, Bing Maps API key
|
1. In the case of Bing Maps, you have to provide your own, personal, generated by you, Bing Maps API key
|
||||||
1. For MapProxy, you need to provide a server URL and layer name to be used
|
1. For MapProxy, you need to provide a server URL and layer name to be used
|
||||||
|
|
||||||
### How to get Bing Maps API key
|
### How to get the Bing Maps API key
|
||||||
|
|
||||||
1. Go to the Bing Maps Dev Center at [https://www.bingmapsportal.com/](https://www.bingmapsportal.com/).
|
1. Go to the Bing Maps Dev Center at [https://www.bingmapsportal.com/](https://www.bingmapsportal.com/).
|
||||||
* If you have a Bing Maps account, sign in with the Microsoft account that you used to create the account or create a new one. For new accounts, follow the instructions in [Creating a Bing Maps Account](https://msdn.microsoft.com/library/gg650598.aspx).
|
* If you have a Bing Maps account, sign in with the Microsoft account that you used to create the account or create a new one. For new accounts, follow the instructions in [Creating a Bing Maps Account](https://msdn.microsoft.com/library/gg650598.aspx).
|
||||||
|
@ -112,18 +145,22 @@ INAV Configurator is shipped **WITHOUT** API key for Bing Maps. That means: ever
|
||||||
1. Select the option to create a new key.
|
1. Select the option to create a new key.
|
||||||
1. Provide the following information to create a key:
|
1. Provide the following information to create a key:
|
||||||
1. Application name: Required. The name of the application.
|
1. Application name: Required. The name of the application.
|
||||||
1. Application URL: The URL of the application. This is an optional field which is useful in helping you remember the purpose of that key in the future.
|
1. Application URL: The URL of the application. This is an optional field that is useful in helping you remember the purpose of that key in the future.
|
||||||
1. Key type: Required. Select the key type that you want to create. You can find descriptions of key and application types here.
|
1. Key type: Required. Select the key type that you want to create. You can find descriptions of key and application types here.
|
||||||
1. Application type: Required. Select the application type that best represents the application that will use this key. You can find descriptions of key and application types [here](https://www.microsoft.com/maps/create-a-bing-maps-key.aspx).
|
1. Application type: Required. Select the application type that best represents the application that will use this key. You can find descriptions of key and application types [here](https://www.microsoft.com/maps/create-a-bing-maps-key.aspx).
|
||||||
1. Click the **Create** button. The new key displays in the list of available keys. Use this key to authenticate your Bing Maps application as described in the documentation for the Bing Maps API you are using.
|
1. Click the **Create** button. The new key is displayed in the list of available keys. Use this key to authenticate your Bing Maps application as described in the documentation for the Bing Maps API you are using.
|
||||||
|
|
||||||
### How to setup a MapProxy server for offline caching and mission planning
|
### How to set up a MapProxy server for offline caching and mission planning
|
||||||
1. Follow process described in [MAPPROXY.md](MAPPROXY.md)
|
1. Follow the process described in [MAPPROXY.md](MAPPROXY.md)
|
||||||
1. Test your MapProxy server in web browser, eg: http://192.168.145.20/inavmapproxy/
|
1. Test your MapProxy server in a web browser, eg: http://192.168.145.20/inavmapproxy/
|
||||||
1. Once you have a working MapProxy server choose MapProxy as your map provider
|
1. Once you have a working MapProxy server choose MapProxy as your map provider
|
||||||
1. Enter MapProxy service URL, eg: http://192.168.145.20/inavmapproxy/service?
|
1. Enter MapProxy service URL, eg: http://192.168.145.20/inavmapproxy/service?
|
||||||
1. Enter MapProxy service layer (inav_layer if configured from MAPPROXY.md)
|
1. Enter MapProxy service layer (inav_layer if configured from MAPPROXY.md)
|
||||||
1. Once completed, you can zoom in on area you will be flying in while connected to the internet in either GPS or Mission Control tab to save the cache for offline use
|
1. Once completed, you can zoom in on the area you will be flying in while connected to the internet in either the GPS or Mission Control tab to save the cache for offline use
|
||||||
|
|
||||||
|
## Font Customisation
|
||||||
|
|
||||||
|
INAV provides the font images so that custom fonts can be created for your personal preference. This is the case for both analogue and digital fonts. The resources can be found in the [osd](/resources/osd) folder. Within the **analogue** and **digital** subfolders, you will find information on compiling your own fonts. There is also an [INAV Character Map](/resources/osd/INAV%20Character%20Map.md) document. This contains previews of all the character images in the fonts and the appropriate variable names within the firmware and Configurator. There are tools for compiling the [analogue](https://github.com/fiam/max7456tool) and [digital](https://github.com/MrD-RC/hdosd-font-tool) fonts. New font submissions via pull requests are welcome.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
@ -131,18 +168,13 @@ INAV Configurator is shipped **WITHOUT** API key for Bing Maps. That means: ever
|
||||||
|
|
||||||
Make sure Settings -> System -> "User hardware acceleration when available" is checked to achieve the best performance
|
Make sure Settings -> System -> "User hardware acceleration when available" is checked to achieve the best performance
|
||||||
|
|
||||||
### Linux users
|
|
||||||
|
|
||||||
1. Dont forget to add your user into dialout group "sudo usermod -aG dialout YOUR_USERNAME" for serial access
|
|
||||||
2. If you have 3D model animation problems, enable "Override software rendering list" in Chrome flags chrome://flags/#ignore-gpu-blacklist
|
|
||||||
|
|
||||||
## Issue trackers
|
## Issue trackers
|
||||||
|
|
||||||
For INAV configurator issues raise them here
|
For INAV configurator issues raise them here
|
||||||
|
|
||||||
https://github.com/iNavFlight/inav-configurator/issues
|
https://github.com/iNavFlight/inav-configurator/issues
|
||||||
|
|
||||||
For INAV firmware issues raise them here
|
For INAV firmware issues, raise them here
|
||||||
|
|
||||||
https://github.com/iNavFlight/inav/issues
|
https://github.com/iNavFlight/inav/issues
|
||||||
|
|
||||||
|
|
23
assets/linux/copyright
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: INAV Configurator
|
||||||
|
Source: https://github.com/iNavFlight/inav-configurator
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: Copyright 2022 The INAV 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'.
|
BIN
assets/linux/icon/inav_icon_128.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
assets/linux/icon/inav_icon_english_128.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
8
assets/linux/inav-configurator.desktop
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=INAV Configurator
|
||||||
|
Comment=Crossplatform configuration tool for the INAV flight control system
|
||||||
|
Exec=/opt/inav/inav-configurator/inav-configurator
|
||||||
|
Icon=/opt/inav/inav-configurator/icon/inav_icon_128.png
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Utility
|
BIN
assets/osx/dmg-background.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
assets/osx/dmg-background.psd
Normal file
BIN
assets/osx/dmg-background@2x.png
Normal file
After Width: | Height: | Size: 108 KiB |
BIN
assets/windows/inav_installer.bmp
Normal file
After Width: | Height: | Size: 151 KiB |
BIN
assets/windows/inav_installer_icon.ico
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
assets/windows/inav_installer_small.bmp
Normal file
After Width: | Height: | Size: 32 KiB |
169
assets/windows/installer.iss
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
; ------------------------------------------
|
||||||
|
; Installer for INAV
|
||||||
|
; ------------------------------------------
|
||||||
|
; It receives from the command line with /D the parameters:
|
||||||
|
; version
|
||||||
|
; archName
|
||||||
|
; archAllowed
|
||||||
|
; archInstallIn64bit
|
||||||
|
; sourceFolder
|
||||||
|
; targetFolder
|
||||||
|
|
||||||
|
#define ApplicationName "INAV Configurator"
|
||||||
|
#define CompanyName "The INAV open source project"
|
||||||
|
#define CompanyUrl "https://github.com/iNavFlight/inav"
|
||||||
|
#define ExecutableFileName "inav-configurator.exe"
|
||||||
|
#define GroupName "INAV"
|
||||||
|
#define InstallerFileName "INAV-Configurator_" + archName + "_" + version
|
||||||
|
#define SourcePath "..\..\" + sourceFolder + "\inav-configurator\" + archName
|
||||||
|
#define TargetFolderName "INAV-Configurator"
|
||||||
|
#define UpdatesUrl "https://github.com/iNavFlight/inav-configurator/releases"
|
||||||
|
|
||||||
|
[CustomMessages]
|
||||||
|
AppName=inav-configurator
|
||||||
|
LaunchProgram=Start {#ApplicationName}
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "{#SourcePath}\*"; DestDir: "{app}"; Flags: recursesubdirs
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
; Programs group
|
||||||
|
Name: "{group}\{#ApplicationName}"; Filename: "{app}\{#ExecutableFileName}";
|
||||||
|
; Desktop icon
|
||||||
|
Name: "{autodesktop}\{#ApplicationName}"; Filename: "{app}\{#ExecutableFileName}";
|
||||||
|
; Non admin users, uninstall icon
|
||||||
|
Name: "{group}\Uninstall {#ApplicationName}"; Filename: "{uninstallexe}"; Check: not IsAdminInstallMode
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
; English default, it must be first
|
||||||
|
Name: "en"; MessagesFile: "compiler:Default.isl"
|
||||||
|
; Official languages
|
||||||
|
;Name: "ca"; MessagesFile: "compiler:Languages\Catalan.isl"
|
||||||
|
;Name: "da"; MessagesFile: "compiler:Languages\Danish.isl"
|
||||||
|
;Name: "de"; MessagesFile: "compiler:Languages\German.isl"
|
||||||
|
;Name: "es"; MessagesFile: "compiler:Languages\Spanish.isl"
|
||||||
|
;Name: "fr"; MessagesFile: "compiler:Languages\French.isl"
|
||||||
|
;Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
|
||||||
|
;Name: "ja"; MessagesFile: "compiler:Languages\Japanese.isl"
|
||||||
|
;Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
|
||||||
|
;Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl"
|
||||||
|
;Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
|
||||||
|
;Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl"
|
||||||
|
; Not official. Sometimes not updated to latest version (strings missing)
|
||||||
|
;Name: "ga"; MessagesFile: "unofficial_inno_languages\Galician.isl"
|
||||||
|
;Name: "eu"; MessagesFile: "unofficial_inno_languages\Basque.isl"
|
||||||
|
;Name: "hr"; MessagesFile: "unofficial_inno_languages\Croatian.isl"
|
||||||
|
;Name: "hu"; MessagesFile: "unofficial_inno_languages\Hungarian.isl"
|
||||||
|
;Name: "id"; MessagesFile: "unofficial_inno_languages\Indonesian.isl"
|
||||||
|
;Name: "ko"; MessagesFile: "unofficial_inno_languages\Korean.isl"
|
||||||
|
;Name: "lv"; MessagesFile: "unofficial_inno_languages\Latvian.isl"
|
||||||
|
;Name: "sv"; MessagesFile: "unofficial_inno_languages\Swedish.isl"
|
||||||
|
;Name: "zh_CN"; MessagesFile: "unofficial_inno_languages\ChineseSimplified.isl"
|
||||||
|
;Name: "zh_TW"; MessagesFile: "unofficial_inno_languages\ChineseTraditional.isl"
|
||||||
|
; Not available
|
||||||
|
; pt_BR (Portuguese Brasileiro)
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
; Add a checkbox to start the app after installed
|
||||||
|
Filename: {app}\{cm:AppName}.exe; Description: {cm:LaunchProgram,{cm:AppName}}; Flags: nowait postinstall skipifsilent
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
AppId=2e5662ca-1fb3-8f1e-a7e1-e390add7a19d
|
||||||
|
AppName={#ApplicationName}
|
||||||
|
AppPublisher={#CompanyName}
|
||||||
|
AppPublisherURL={#CompanyUrl}
|
||||||
|
AppUpdatesURL={#UpdatesUrl}
|
||||||
|
AppVersion={#version}
|
||||||
|
ArchitecturesAllowed={#archAllowed}
|
||||||
|
ArchitecturesInstallIn64BitMode={#archInstallIn64bit}
|
||||||
|
Compression=lzma2
|
||||||
|
DefaultDirName={autopf}\{#GroupName}\{#TargetFolderName}
|
||||||
|
DefaultGroupName={#GroupName}\{#ApplicationName}
|
||||||
|
LicenseFile=..\..\LICENSE
|
||||||
|
MinVersion=6.2
|
||||||
|
OutputBaseFilename={#InstallerFileName}
|
||||||
|
OutputDir=..\..\{#targetFolder}\
|
||||||
|
PrivilegesRequiredOverridesAllowed=commandline dialog
|
||||||
|
SetupIconFile=inav_installer_icon.ico
|
||||||
|
ShowLanguageDialog=yes
|
||||||
|
SolidCompression=yes
|
||||||
|
UninstallDisplayIcon={app}\{#ExecutableFileName}
|
||||||
|
UninstallDisplayName={#ApplicationName}
|
||||||
|
WizardImageFile=inav_installer.bmp
|
||||||
|
WizardSmallImageFile=inav_installer_small.bmp
|
||||||
|
WizardStyle=modern
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
function GetOldNsisUninstallerPath(): String;
|
||||||
|
var
|
||||||
|
RegKey: String;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
// Look into the different registry entries: win32, win64 and without user rights
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\INAV Configurator', 'UninstallString', Result) then
|
||||||
|
begin
|
||||||
|
if not RegQueryStringValue(HKLM, 'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\INAV Configurator', 'UninstallString', Result) then
|
||||||
|
begin
|
||||||
|
RegQueryStringValue(HKCU, 'SOFTWARE\INAV\INAV Configurator', 'UninstallString', Result)
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetQuietUninstallerPath(): String;
|
||||||
|
var
|
||||||
|
RegKey: String;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
RegKey := Format('%s\%s_is1', ['Software\Microsoft\Windows\CurrentVersion\Uninstall', '{#emit SetupSetting("AppId")}']);
|
||||||
|
if not RegQueryStringValue(HKEY_LOCAL_MACHINE, RegKey, 'QuietUninstallString', Result) then
|
||||||
|
begin
|
||||||
|
RegQueryStringValue(HKEY_CURRENT_USER, RegKey, 'QuietUninstallString', Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function InitializeSetup(): Boolean;
|
||||||
|
var
|
||||||
|
ResultCode: Integer;
|
||||||
|
ParameterStr : String;
|
||||||
|
UninstPath : String;
|
||||||
|
begin
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
|
||||||
|
// Check if the application is already installed by the old NSIS installer, and uninstall it
|
||||||
|
UninstPath := GetOldNsisUninstallerPath();
|
||||||
|
|
||||||
|
// Found, start uninstall
|
||||||
|
if UninstPath <> '' then
|
||||||
|
begin
|
||||||
|
|
||||||
|
UninstPath := RemoveQuotes(UninstPath);
|
||||||
|
|
||||||
|
// Add this parameter to not return until uninstall finished. The drawback is that the uninstaller file is not deleted
|
||||||
|
ParameterStr := '_?=' + ExtractFilePath(UninstPath);
|
||||||
|
|
||||||
|
if Exec(UninstPath, ParameterStr, '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
|
||||||
|
begin
|
||||||
|
// Delete the unistaller file and empty folders. Not deleting the files.
|
||||||
|
DeleteFile(UninstPath);
|
||||||
|
DelTree(ExtractFilePath(UninstPath), True, False, True);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
Result := False;
|
||||||
|
MsgBox('Error uninstalling old Configurator ' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
|
||||||
|
// Search for new Inno Setup installations
|
||||||
|
UninstPath := GetQuietUninstallerPath();
|
||||||
|
if UninstPath <> '' then
|
||||||
|
begin
|
||||||
|
if not Exec('>', UninstPath, '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
MsgBox('Error uninstalling Configurator ' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
442
gulpfile.js
|
@ -13,6 +13,8 @@ var semver = require('semver');
|
||||||
var gulp = require('gulp');
|
var gulp = require('gulp');
|
||||||
var concat = require('gulp-concat');
|
var concat = require('gulp-concat');
|
||||||
|
|
||||||
|
const commandExistsSync = require('command-exists').sync;
|
||||||
|
|
||||||
// Each key in the *sources* variable must be an array of
|
// Each key in the *sources* variable must be an array of
|
||||||
// the source files that will be combined into a single
|
// the source files that will be combined into a single
|
||||||
// file and stored in *outputDir*. Each key in *sources*
|
// file and stored in *outputDir*. Each key in *sources*
|
||||||
|
@ -124,6 +126,7 @@ sources.js = [
|
||||||
'./js/serial_queue.js',
|
'./js/serial_queue.js',
|
||||||
'./js/msp_balanced_interval.js',
|
'./js/msp_balanced_interval.js',
|
||||||
'./tabs/advanced_tuning.js',
|
'./tabs/advanced_tuning.js',
|
||||||
|
'./tabs/ez_tune.js',
|
||||||
'./js/peripherals.js',
|
'./js/peripherals.js',
|
||||||
'./js/appUpdater.js',
|
'./js/appUpdater.js',
|
||||||
'./js/feature_framework.js',
|
'./js/feature_framework.js',
|
||||||
|
@ -135,6 +138,9 @@ sources.js = [
|
||||||
'./js/waypoint.js',
|
'./js/waypoint.js',
|
||||||
'./node_modules/openlayers/dist/ol.js',
|
'./node_modules/openlayers/dist/ol.js',
|
||||||
'./js/libraries/plotly-latest.min.js',
|
'./js/libraries/plotly-latest.min.js',
|
||||||
|
'./js/sitl.js',
|
||||||
|
'./js/CliAutoComplete.js',
|
||||||
|
'./node_modules/jquery-textcomplete/dist/jquery.textcomplete.js'
|
||||||
];
|
];
|
||||||
|
|
||||||
sources.receiverCss = [
|
sources.receiverCss = [
|
||||||
|
@ -249,8 +255,10 @@ gulp.task('dist-build', gulp.series('build', function() {
|
||||||
'./src/css/opensans_webfontkit/*.{eot,svg,ttf,woff,woff2}',
|
'./src/css/opensans_webfontkit/*.{eot,svg,ttf,woff,woff2}',
|
||||||
'./resources/*.json',
|
'./resources/*.json',
|
||||||
'./resources/models/*',
|
'./resources/models/*',
|
||||||
'./resources/osd/*.mcm',
|
'./resources/osd/analogue/*.mcm',
|
||||||
'./resources/motor_order/*.svg',
|
'./resources/motor_order/*.svg',
|
||||||
|
'./resources/sitl/windows/*',
|
||||||
|
'./resources/sitl/linux/*'
|
||||||
];
|
];
|
||||||
return gulp.src(distSources, { base: '.' })
|
return gulp.src(distSources, { base: '.' })
|
||||||
.pipe(gulp.dest(distDir));
|
.pipe(gulp.dest(distDir));
|
||||||
|
@ -267,7 +275,8 @@ gulp.task('apps', gulp.series('dist', function(done) {
|
||||||
flavor: 'normal',
|
flavor: 'normal',
|
||||||
macIcns: './images/inav.icns',
|
macIcns: './images/inav.icns',
|
||||||
winIco: './images/inav.ico',
|
winIco: './images/inav.ico',
|
||||||
version: get_nw_version()
|
version: get_nw_version(),
|
||||||
|
zip: false
|
||||||
});
|
});
|
||||||
builder.on('log', console.log);
|
builder.on('log', console.log);
|
||||||
builder.build(function (err) {
|
builder.build(function (err) {
|
||||||
|
@ -285,38 +294,79 @@ function get_nw_version() {
|
||||||
return semver.valid(semver.coerce(require('./package.json').dependencies.nw));
|
return semver.valid(semver.coerce(require('./package.json').dependencies.nw));
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_release_filename(platform, ext) {
|
function get_release_filename_base(platform) {
|
||||||
var pkg = require('./package.json');
|
return 'INAV-Configurator_' + platform;
|
||||||
return 'INAV-Configurator_' + platform + '_' + pkg.version + '.' + ext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp.task('release-win32', function() {
|
function get_release_filename(platform, ext, addition = '') {
|
||||||
var pkg = require('./package.json');
|
var pkg = require('./package.json');
|
||||||
var src = path.join(appsDir, pkg.name, 'win32');
|
return get_release_filename_base(platform) + addition + '_' + pkg.version + '.' + ext;
|
||||||
var output = fs.createWriteStream(path.join(appsDir, get_release_filename('win32', 'zip')));
|
}
|
||||||
var archive = archiver('zip', {
|
|
||||||
zlib: { level: 9 }
|
|
||||||
});
|
|
||||||
archive.on('warning', function(err) { throw err; });
|
|
||||||
archive.on('error', function(err) { throw err; });
|
|
||||||
archive.pipe(output);
|
|
||||||
archive.directory(src, 'INAV Configurator');
|
|
||||||
return archive.finalize();
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('release-win64', function() {
|
function build_win_zip(arch) {
|
||||||
var pkg = require('./package.json');
|
return function build_win_zip_proc(done) {
|
||||||
var src = path.join(appsDir, pkg.name, 'win64');
|
var pkg = require('./package.json');
|
||||||
var output = fs.createWriteStream(path.join(appsDir, get_release_filename('win64', 'zip')));
|
|
||||||
var archive = archiver('zip', {
|
// Create ZIP
|
||||||
zlib: { level: 9 }
|
console.log(`Creating ${arch} ZIP file...`);
|
||||||
});
|
var src = path.join(appsDir, pkg.name, arch);
|
||||||
archive.on('warning', function(err) { throw err; });
|
var output = fs.createWriteStream(path.join(appsDir, get_release_filename(arch, 'zip')));
|
||||||
archive.on('error', function(err) { throw err; });
|
var archive = archiver('zip', {
|
||||||
archive.pipe(output);
|
zlib: { level: 9 }
|
||||||
archive.directory(src, 'INAV Configurator');
|
});
|
||||||
return archive.finalize();
|
archive.on('warning', function(err) { throw err; });
|
||||||
});
|
archive.on('error', function(err) { throw err; });
|
||||||
|
archive.pipe(output);
|
||||||
|
archive.directory(src, 'INAV Configurator');
|
||||||
|
return archive.finalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function build_win_iss(arch) {
|
||||||
|
return function build_win_iss_proc(done) {
|
||||||
|
if (!getArguments().installer) {
|
||||||
|
done();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Installer
|
||||||
|
console.log(`Creating ${arch} Installer...`);
|
||||||
|
const innoSetup = require('@quanle94/innosetup');
|
||||||
|
|
||||||
|
const APPS_DIR = './apps/';
|
||||||
|
const pkg = require('./package.json');
|
||||||
|
|
||||||
|
// Parameters passed to the installer script
|
||||||
|
const parameters = [];
|
||||||
|
|
||||||
|
// Extra parameters to replace inside the iss file
|
||||||
|
parameters.push(`/Dversion=${pkg.version}`);
|
||||||
|
parameters.push(`/DarchName=${arch}`);
|
||||||
|
parameters.push(`/DarchAllowed=${(arch === 'win32') ? 'x86 x64' : 'x64'}`);
|
||||||
|
parameters.push(`/DarchInstallIn64bit=${(arch === 'win32') ? '' : 'x64'}`);
|
||||||
|
parameters.push(`/DsourceFolder=${APPS_DIR}`);
|
||||||
|
parameters.push(`/DtargetFolder=${APPS_DIR}`);
|
||||||
|
|
||||||
|
// Show only errors in console
|
||||||
|
parameters.push(`/Q`);
|
||||||
|
|
||||||
|
// Script file to execute
|
||||||
|
parameters.push("assets/windows/installer.iss");
|
||||||
|
|
||||||
|
innoSetup(parameters, {},
|
||||||
|
function(error) {
|
||||||
|
if (error != null) {
|
||||||
|
console.error(`Installer for platform ${arch} finished with error ${error}`);
|
||||||
|
} else {
|
||||||
|
console.log(`Installer for platform ${arch} finished`);
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gulp.task('release-win32', gulp.series(build_win_zip('win32'), build_win_iss('win32')));
|
||||||
|
gulp.task('release-win64', gulp.series(build_win_zip('win64'), build_win_iss('win64')));
|
||||||
|
|
||||||
gulp.task('release-osx64', function(done) {
|
gulp.task('release-osx64', function(done) {
|
||||||
var pkg = require('./package.json');
|
var pkg = require('./package.json');
|
||||||
|
@ -337,37 +387,317 @@ gulp.task('release-osx64', function(done) {
|
||||||
codesignArgs.push('-e', 'entitlements.plist');
|
codesignArgs.push('-e', 'entitlements.plist');
|
||||||
codesignArgs.push(src)
|
codesignArgs.push(src)
|
||||||
execSync.apply(this, codesignArgs);
|
execSync.apply(this, codesignArgs);
|
||||||
|
|
||||||
|
// Check if the bundle is signed
|
||||||
|
const codesignCheckArgs = [ 'codesign', '-vvv', '--deep', '--strict', src ];
|
||||||
|
execSync.apply(this, codesignCheckArgs);
|
||||||
}
|
}
|
||||||
const zipFilename = path.join(appsDir, get_release_filename('macOS', 'zip'));
|
|
||||||
var output = fs.createWriteStream(zipFilename);
|
// 'old' .zip mode
|
||||||
var archive = archiver('zip', {
|
if (!getArguments().installer) {
|
||||||
zlib: { level: 9 }
|
const zipFilename = path.join(appsDir, get_release_filename('macOS', 'zip'));
|
||||||
});
|
console.log('Creating ZIP file: ' + zipFilename);
|
||||||
archive.on('warning', function(err) { throw err; });
|
var output = fs.createWriteStream(zipFilename);
|
||||||
archive.on('error', function(err) { throw err; });
|
var archive = archiver('zip', {
|
||||||
archive.pipe(output);
|
zlib: { level: 9 }
|
||||||
archive.directory(src, 'INAV Configurator.app');
|
});
|
||||||
output.on('close', function() {
|
archive.on('warning', function(err) { throw err; });
|
||||||
if (getArguments().notarize) {
|
archive.on('error', function(err) { throw err; });
|
||||||
const notarizeArgs = ['macapptool', '-v', '1', 'notarize'];
|
archive.pipe(output);
|
||||||
const notarizationUsername = getArguments()['notarization-username'];
|
archive.directory(src, 'INAV Configurator.app');
|
||||||
if (notarizationUsername) {
|
output.on('close', function() {
|
||||||
notarizeArgs.push('-u', notarizationUsername)
|
if (getArguments().notarize) {
|
||||||
|
console.log('Notarizing DMG file: ' + zipFilename);
|
||||||
|
const notarizeArgs = ['macapptool', '-v', '1', 'notarize'];
|
||||||
|
const notarizationUsername = getArguments()['notarization-username'];
|
||||||
|
if (notarizationUsername) {
|
||||||
|
notarizeArgs.push('-u', notarizationUsername)
|
||||||
|
}
|
||||||
|
const notarizationPassword = getArguments()['notarization-password'];
|
||||||
|
if (notarizationPassword) {
|
||||||
|
notarizeArgs.push('-p', notarizationPassword)
|
||||||
|
}
|
||||||
|
notarizeArgs.push(zipFilename)
|
||||||
|
execSync.apply(this, notarizeArgs);
|
||||||
}
|
}
|
||||||
const notarizationPassword = getArguments()['notarization-password'];
|
done();
|
||||||
if (notarizationPassword) {
|
});
|
||||||
notarizeArgs.push('-p', notarizationPassword)
|
archive.finalize();
|
||||||
}
|
}
|
||||||
notarizeArgs.push(zipFilename)
|
// 'new' .dmg mode
|
||||||
execSync.apply(this, notarizeArgs);
|
else {
|
||||||
|
const appdmg = require('appdmg');
|
||||||
|
|
||||||
|
var target = path.join(appsDir, get_release_filename('macOS', 'dmg'));
|
||||||
|
console.log('Creating DMG file: ' + target);
|
||||||
|
var basepath = path.join(appsDir, pkg.name, 'osx64');
|
||||||
|
console.log('Base path: ' + basepath);
|
||||||
|
|
||||||
|
if (fs.existsSync(target)) {
|
||||||
|
fs.unlinkSync(target);
|
||||||
}
|
}
|
||||||
done();
|
|
||||||
});
|
var specs = {};
|
||||||
archive.finalize();
|
|
||||||
|
specs["title"] = "INAV Configurator";
|
||||||
|
specs["contents"] = [
|
||||||
|
{ "x": 448, "y": 342, "type": "link", "path": "/Applications" },
|
||||||
|
{ "x": 192, "y": 344, "type": "file", "path": pkg.name + ".app", "name": "INAV Configurator.app" },
|
||||||
|
];
|
||||||
|
specs["background"] = path.join(__dirname, 'assets/osx/dmg-background.png');
|
||||||
|
specs["format"] = "UDZO";
|
||||||
|
specs["window"] = {
|
||||||
|
"size": {
|
||||||
|
"width": 638,
|
||||||
|
"height": 479,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const codesignIdentity = getArguments()['codesign-identity'];
|
||||||
|
if (getArguments().codesign) {
|
||||||
|
specs['code-sign'] = {
|
||||||
|
'signing-identity': codesignIdentity,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ee = appdmg({
|
||||||
|
target: target,
|
||||||
|
basepath: basepath,
|
||||||
|
specification: specs,
|
||||||
|
});
|
||||||
|
|
||||||
|
ee.on('progress', function(info) {
|
||||||
|
//console.log(info);
|
||||||
|
});
|
||||||
|
|
||||||
|
ee.on('error', function(err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
ee.on('finish', function() {
|
||||||
|
if (getArguments().codesign) {
|
||||||
|
// Check if the bundle is signed
|
||||||
|
const codesignCheckArgs = [ 'codesign', '-vvv', '--deep', '--strict', target ];
|
||||||
|
execSync.apply(this, codesignCheckArgs);
|
||||||
|
}
|
||||||
|
if (getArguments().notarize) {
|
||||||
|
console.log('Notarizing DMG file: ' + target);
|
||||||
|
const notarizeArgs = ['xcrun', 'notarytool', 'submit'];
|
||||||
|
notarizeArgs.push(target);
|
||||||
|
const notarizationUsername = getArguments()['notarization-username'];
|
||||||
|
if (notarizationUsername) {
|
||||||
|
notarizeArgs.push('--apple-id', notarizationUsername)
|
||||||
|
} else {
|
||||||
|
throw new Error('Missing notarization username');
|
||||||
|
}
|
||||||
|
const notarizationPassword = getArguments()['notarization-password'];
|
||||||
|
if (notarizationPassword) {
|
||||||
|
notarizeArgs.push('--password', notarizationPassword)
|
||||||
|
} else {
|
||||||
|
throw new Error('Missing notarization password');
|
||||||
|
}
|
||||||
|
const notarizationTeamId = getArguments()['notarization-team-id'];
|
||||||
|
if (notarizationTeamId) {
|
||||||
|
notarizeArgs.push('--team-id', notarizationTeamId)
|
||||||
|
} else {
|
||||||
|
throw new Error('Missing notarization Team ID');
|
||||||
|
}
|
||||||
|
notarizeArgs.push('--wait');
|
||||||
|
|
||||||
|
const notarizationWebhook = getArguments()['notarization-webhook'];
|
||||||
|
if (notarizationWebhook) {
|
||||||
|
notarizeArgs.push('--webhook', notarizationWebhook);
|
||||||
|
}
|
||||||
|
execSync.apply(this, notarizeArgs);
|
||||||
|
|
||||||
|
console.log('Stapling DMG file: ' + target);
|
||||||
|
const stapleArgs = ['xcrun', 'stapler', 'staple'];
|
||||||
|
stapleArgs.push(target);
|
||||||
|
execSync.apply(this, stapleArgs);
|
||||||
|
|
||||||
|
console.log('Checking DMG file: ' + target);
|
||||||
|
const checkArgs = ['spctl', '-vvv', '--assess', '--type', 'install', target];
|
||||||
|
execSync.apply(this, checkArgs);
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function post_build(arch, folder) {
|
||||||
|
return function post_build_linux(done) {
|
||||||
|
if ((arch === 'linux32') || (arch === 'linux64')) {
|
||||||
|
const metadata = require('./package.json');
|
||||||
|
// Copy Ubuntu launcher scripts to destination dir
|
||||||
|
const launcherDir = path.join(folder, metadata.name, arch);
|
||||||
|
console.log(`Copy Ubuntu launcher scripts to ${launcherDir}`);
|
||||||
|
return gulp.src('assets/linux/**')
|
||||||
|
.pipe(gulp.dest(launcherDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the dir directory, with write permissions
|
||||||
|
function createDirIfNotExists(dir) {
|
||||||
|
fs.mkdir(dir, '0775', function(err) {
|
||||||
|
if (err && err.code !== 'EEXIST') {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function release_deb(arch) {
|
||||||
|
return function release_deb_proc(done) {
|
||||||
|
if (!getArguments().installer) {
|
||||||
|
done();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if dpkg-deb exists
|
||||||
|
if (!commandExistsSync('dpkg-deb')) {
|
||||||
|
console.warn(`dpkg-deb command not found, not generating deb package for ${arch}`);
|
||||||
|
done();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deb = require('gulp-debian');
|
||||||
|
const LINUX_INSTALL_DIR = '/opt/inav';
|
||||||
|
const metadata = require('./package.json');
|
||||||
|
|
||||||
|
console.log(`Generating deb package for ${arch}`);
|
||||||
|
|
||||||
|
return gulp.src([path.join(appsDir, metadata.name, arch, '*')])
|
||||||
|
.pipe(deb({
|
||||||
|
package: metadata.name,
|
||||||
|
version: metadata.version,
|
||||||
|
section: 'base',
|
||||||
|
priority: 'optional',
|
||||||
|
architecture: getLinuxPackageArch('deb', arch),
|
||||||
|
maintainer: metadata.author,
|
||||||
|
description: metadata.description,
|
||||||
|
preinst: [`rm -rf ${LINUX_INSTALL_DIR}/${metadata.name}`],
|
||||||
|
postinst: [
|
||||||
|
`chown root:root ${LINUX_INSTALL_DIR}`,
|
||||||
|
`chown -R root:root ${LINUX_INSTALL_DIR}/${metadata.name}`,
|
||||||
|
`xdg-desktop-menu install ${LINUX_INSTALL_DIR}/${metadata.name}/${metadata.name}.desktop`,
|
||||||
|
],
|
||||||
|
prerm: [`xdg-desktop-menu uninstall ${metadata.name}.desktop`],
|
||||||
|
depends: ['libgconf-2-4', 'libatomic1'],
|
||||||
|
changelog: [],
|
||||||
|
_target: `${LINUX_INSTALL_DIR}/${metadata.name}`,
|
||||||
|
_out: appsDir,
|
||||||
|
_copyright: 'assets/linux/copyright',
|
||||||
|
_clean: true,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function post_release_deb(arch) {
|
||||||
|
return function post_release_linux_deb(done) {
|
||||||
|
if (!getArguments().installer) {
|
||||||
|
done();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ((arch === 'linux32') || (arch === 'linux64')) {
|
||||||
|
var rename = require("gulp-rename");
|
||||||
|
const metadata = require('./package.json');
|
||||||
|
const renameFrom = path.join(appsDir, metadata.name + '_' + metadata.version + '_' + getLinuxPackageArch('.deb', arch) + '.deb');
|
||||||
|
const renameTo = path.join(appsDir, get_release_filename_base(arch) + '_' + metadata.version + '.deb');
|
||||||
|
// Rename .deb build to common naming
|
||||||
|
console.log(`Renaming .deb installer ${renameFrom} to ${renameTo}`);
|
||||||
|
return gulp.src(renameFrom)
|
||||||
|
.pipe(rename(renameTo))
|
||||||
|
.pipe(gulp.dest("."));
|
||||||
|
}
|
||||||
|
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function release_rpm(arch) {
|
||||||
|
return function release_rpm_proc(done) {
|
||||||
|
if (!getArguments().installer) {
|
||||||
|
done();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if rpmbuild exists
|
||||||
|
if (!commandExistsSync('rpmbuild')) {
|
||||||
|
console.warn(`rpmbuild command not found, not generating rpm package for ${arch}`);
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildRpm = require('rpm-builder');
|
||||||
|
const NAME_REGEX = /-/g;
|
||||||
|
const LINUX_INSTALL_DIR = '/opt/inav';
|
||||||
|
const metadata = require('./package.json');
|
||||||
|
|
||||||
|
console.log(`Generating rpm package for ${arch}`);
|
||||||
|
|
||||||
|
// The buildRpm does not generate the folder correctly, manually
|
||||||
|
createDirIfNotExists(appsDir);
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
name: get_release_filename_base(arch), // metadata.name,
|
||||||
|
version: metadata.version.replace(NAME_REGEX, '_'), // RPM does not like release candidate versions
|
||||||
|
buildArch: getLinuxPackageArch('rpm', arch),
|
||||||
|
vendor: metadata.author,
|
||||||
|
summary: metadata.description,
|
||||||
|
license: 'GNU General Public License v3.0',
|
||||||
|
requires: ['libatomic1'],
|
||||||
|
prefix: '/opt',
|
||||||
|
files: [{
|
||||||
|
cwd: path.join(appsDir, metadata.name, arch),
|
||||||
|
src: '*',
|
||||||
|
dest: `${LINUX_INSTALL_DIR}/${metadata.name}`,
|
||||||
|
}],
|
||||||
|
postInstallScript: [`xdg-desktop-menu install ${LINUX_INSTALL_DIR}/${metadata.name}/${metadata.name}.desktop`],
|
||||||
|
preUninstallScript: [`xdg-desktop-menu uninstall ${metadata.name}.desktop`],
|
||||||
|
tempDir: path.join(appsDir, `tmp-rpm-build-${arch}`),
|
||||||
|
keepTemp: false,
|
||||||
|
verbose: false,
|
||||||
|
rpmDest: appsDir,
|
||||||
|
execOpts: { maxBuffer: 1024 * 1024 * 16 },
|
||||||
|
};
|
||||||
|
|
||||||
|
buildRpm(options, function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(`Error generating rpm package: ${err}`);
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLinuxPackageArch(type, arch) {
|
||||||
|
let packArch;
|
||||||
|
|
||||||
|
switch (arch) {
|
||||||
|
case 'linux32':
|
||||||
|
packArch = 'i386';
|
||||||
|
break;
|
||||||
|
case 'linux64':
|
||||||
|
if (type === 'rpm') {
|
||||||
|
packArch = 'x86_64';
|
||||||
|
} else {
|
||||||
|
packArch = 'amd64';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`Package error, arch: ${arch}`);
|
||||||
|
process.exit(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return packArch;
|
||||||
|
}
|
||||||
|
|
||||||
function releaseLinux(bits) {
|
function releaseLinux(bits) {
|
||||||
return function() {
|
return function() {
|
||||||
|
console.log(`Generating zip package for linux${bits}`);
|
||||||
var dirname = 'linux' + bits;
|
var dirname = 'linux' + bits;
|
||||||
var pkg = require('./package.json');
|
var pkg = require('./package.json');
|
||||||
var src = path.join(appsDir, pkg.name, dirname);
|
var src = path.join(appsDir, pkg.name, dirname);
|
||||||
|
@ -384,8 +714,8 @@ function releaseLinux(bits) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp.task('release-linux32', releaseLinux(32));
|
gulp.task('release-linux32', gulp.series(releaseLinux(32), post_build('linux32', appsDir), release_deb('linux32'), post_release_deb('linux32')));
|
||||||
gulp.task('release-linux64', releaseLinux(64));
|
gulp.task('release-linux64', gulp.series(releaseLinux(64), post_build('linux64', appsDir), release_deb('linux64'), post_release_deb('linux64'), release_rpm('linux64')));
|
||||||
|
|
||||||
// Create distributable .zip files in ./apps
|
// Create distributable .zip files in ./apps
|
||||||
gulp.task('release', gulp.series('apps', getPlatforms().map(function(v) { return 'release-' + v; })));
|
gulp.task('release', gulp.series('apps', getPlatforms().map(function(v) { return 'release-' + v; })));
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
viewBox="0 0 141.7 141.7" enable-background="new 0 0 141.7 141.7" xml:space="preserve">
|
width="283.46px" height="141.73px" viewBox="0 0 283.46 141.73" enable-background="new 0 0 283.46 141.73" xml:space="preserve">
|
||||||
<g>
|
<g>
|
||||||
<path fill="#FFFFFF" d="M137.9,36.3c-0.1-1.2-0.9-2.2-2-2.6c-1.1-0.4-2.4-0.1-3.2,0.7l-17.4,17.4l-19.3-6.1l-6.1-19.3l17.4-17.4
|
<circle fill="#999999" cx="141.73" cy="100.25" r="5.271"/>
|
||||||
c0.9-0.9,1.1-2.1,0.7-3.2c-0.4-1.1-1.4-1.9-2.6-2C94.7,2.7,84.3,6.5,76.8,14c-10.3,10.3-13,25.3-8.2,38c-0.5,0.4-1,0.9-1.6,1.4
|
<path fill="#999999" d="M160.347,114.468h-37.234c0.025,7.52-4.19,12.583-9.941,16.749h57.114
|
||||||
L9,108.3c0,0,0,0-0.1,0.1c-6.8,6.8-6.8,18,0,24.8c6.8,6.8,17.9,6.8,24.7-0.1c0,0,0.1-0.1,0.1-0.1l54.4-58.6c0.5-0.5,1-1,1.4-1.6
|
C163.099,126.682,160.447,120.906,160.347,114.468z"/>
|
||||||
c12.8,4.8,27.8,2.1,38-8.2C135,57.2,138.8,46.9,137.9,36.3z M24.9,125.8c-2.5,2.5-6.6,2.5-9.1,0c-2.5-2.5-2.5-6.6,0-9.1
|
<path fill="#999999" d="M213.125,6H70.336c-2.261,0-4.104,1.843-4.104,4.104v94.594c0,2.262,1.843,4.104,4.104,4.104h142.789
|
||||||
c2.5-2.5,6.6-2.5,9.1,0C27.4,119.2,27.4,123.3,24.9,125.8z"/>
|
c2.262,0,4.104-1.844,4.104-4.104V10.104C217.228,7.843,215.386,6,213.125,6z M141.73,105.521c-2.912,0-5.271-2.359-5.271-5.271
|
||||||
|
s2.359-5.271,5.271-5.271s5.272,2.359,5.272,5.271S144.642,105.521,141.73,105.521z M208.515,88.036
|
||||||
|
c0,1.99-1.633,3.624-3.623,3.624H78.581c-1.99,0-3.625-1.634-3.625-3.624V17.354c-0.012-1.991,1.622-3.625,3.625-3.625h126.311
|
||||||
|
c2.002,0,3.623,1.634,3.623,3.625V88.036z"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 934 B After Width: | Height: | Size: 1.2 KiB |
16
images/icons/cf_icon_sitl_grey.svg
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="141.7px" height="141.7px" viewBox="0 0 141.7 141.7" enable-background="new 0 0 141.7 141.7" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<circle fill="#9A9999" cx="70.85" cy="102.911" r="4.754"/>
|
||||||
|
<path fill="#9A9999" d="M87.639,115.732H54.062c0.021,6.782-3.779,11.349-8.966,15.105h51.508
|
||||||
|
C90.122,126.748,87.729,121.538,87.639,115.732z"/>
|
||||||
|
<path fill="#9A9999" d="M135.235,17.913H6.465c-2.039,0-3.701,1.663-3.701,3.702v85.308c0,2.04,1.662,3.7,3.701,3.7h128.771
|
||||||
|
c2.039,0,3.701-1.662,3.701-3.7V21.615C138.937,19.576,137.274,17.913,135.235,17.913z M70.85,107.665
|
||||||
|
c-2.626,0-4.754-2.128-4.754-4.754c0-2.627,2.128-4.755,4.754-4.755c2.628,0,4.756,2.128,4.756,4.755
|
||||||
|
C75.605,105.537,73.478,107.665,70.85,107.665z M131.079,91.896c0,1.795-1.474,3.269-3.27,3.269H13.9
|
||||||
|
c-1.796,0-3.269-1.474-3.269-3.269V28.153c-0.011-1.795,1.462-3.269,3.269-3.269H127.81c1.807,0,3.27,1.474,3.27,3.269V91.896z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
16
images/icons/cf_icon_sitl_white.svg
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="141.7px" height="141.7px" viewBox="0 0 141.7 141.7" enable-background="new 0 0 141.7 141.7" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<circle fill="#FFFFFF" cx="70.85" cy="102.911" r="4.754"/>
|
||||||
|
<path fill="#FFFFFF" d="M87.639,115.732H54.062c0.021,6.782-3.779,11.349-8.966,15.105h51.508
|
||||||
|
C90.122,126.748,87.729,121.538,87.639,115.732z"/>
|
||||||
|
<path fill="#FFFFFF" d="M135.235,17.913H6.465c-2.039,0-3.701,1.663-3.701,3.702v85.308c0,2.04,1.662,3.7,3.701,3.7h128.771
|
||||||
|
c2.039,0,3.701-1.662,3.701-3.7V21.615C138.937,19.576,137.274,17.913,135.235,17.913z M70.85,107.665
|
||||||
|
c-2.626,0-4.754-2.128-4.754-4.754c0-2.627,2.128-4.755,4.754-4.755c2.628,0,4.756,2.128,4.756,4.755
|
||||||
|
C75.605,105.537,73.478,107.665,70.85,107.665z M131.079,91.896c0,1.795-1.474,3.269-3.27,3.269H13.9
|
||||||
|
c-1.796,0-3.269-1.474-3.269-3.269V28.153c-0.011-1.795,1.462-3.269,3.269-3.269H127.81c1.807,0,3.27,1.474,3.27,3.269V91.896z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 5.4 KiB |
BIN
images/inav.ico
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 44 KiB |
554
js/CliAutoComplete.js
Normal file
|
@ -0,0 +1,554 @@
|
||||||
|
/**
|
||||||
|
* Encapsulates the AutoComplete logic
|
||||||
|
*
|
||||||
|
* Uses: https://github.com/yuku/jquery-textcomplete
|
||||||
|
* Check out the docs at https://github.com/yuku/jquery-textcomplete/tree/v1/doc
|
||||||
|
*/
|
||||||
|
const CliAutoComplete = {
|
||||||
|
configEnabled: false,
|
||||||
|
builder: { state: 'reset', numFails: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete.isEnabled = function() {
|
||||||
|
return this.isBuilding() || (this.configEnabled && CONFIG.flightControllerIdentifier === "INAV" && this.builder.state !== 'fail');
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete.isBuilding = function() {
|
||||||
|
return this.builder.state !== 'reset' && this.builder.state !== 'done' && this.builder.state !== 'fail';
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete.isOpen = function() {
|
||||||
|
return $('.cli-textcomplete-dropdown').is(':visible');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} force - Forces AutoComplete to be shown even if the matching strategy has less that minChars input
|
||||||
|
*/
|
||||||
|
CliAutoComplete.openLater = function(force) {
|
||||||
|
const self = this;
|
||||||
|
setTimeout(function() {
|
||||||
|
self.forceOpen = !!force;
|
||||||
|
self.$textarea.textcomplete('trigger');
|
||||||
|
self.forceOpen = false;
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete.setEnabled = function(enable) {
|
||||||
|
if (this.configEnabled !== enable) {
|
||||||
|
this.configEnabled = enable;
|
||||||
|
|
||||||
|
if (CONFIGURATOR.cliActive && CONFIGURATOR.cliValid) {
|
||||||
|
// cli is already open
|
||||||
|
if (this.isEnabled()) {
|
||||||
|
this.builderStart();
|
||||||
|
} else if (!this.isEnabled() && !this.isBuilding()) {
|
||||||
|
this.cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete.initialize = function($textarea, sendLine, writeToOutput) {
|
||||||
|
this.$textarea = $textarea;
|
||||||
|
this.forceOpen = false;
|
||||||
|
this.sendLine = sendLine;
|
||||||
|
this.writeToOutput = writeToOutput;
|
||||||
|
this.cleanup();
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete.cleanup = function() {
|
||||||
|
this.$textarea.textcomplete('destroy');
|
||||||
|
this.builder.state = 'reset';
|
||||||
|
this.builder.numFails = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete._builderWatchdogTouch = function() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
this._builderWatchdogStop();
|
||||||
|
|
||||||
|
helper.timeout.add('autocomplete_builder_watchdog', function() {
|
||||||
|
if (self.builder.numFails) {
|
||||||
|
self.builder.numFails++;
|
||||||
|
self.builder.state = 'fail';
|
||||||
|
self.writeToOutput('Failed!<br># ');
|
||||||
|
$(self).trigger('build:stop');
|
||||||
|
} else {
|
||||||
|
// give it one more try
|
||||||
|
self.builder.state = 'reset';
|
||||||
|
self.builderStart();
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete._builderWatchdogStop = function() {
|
||||||
|
helper.timeout.remove('autocomplete_builder_watchdog');
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete.builderStart = function() {
|
||||||
|
if (this.builder.state === 'reset') {
|
||||||
|
this.cache = {
|
||||||
|
commands: [],
|
||||||
|
resources: [],
|
||||||
|
resourcesCount: {},
|
||||||
|
settings: [],
|
||||||
|
settingsAcceptedValues: {},
|
||||||
|
feature: [],
|
||||||
|
beeper: ['ALL'],
|
||||||
|
};
|
||||||
|
this.builder.commandSequence = ['help', 'dump', 'get'];
|
||||||
|
this.builder.currentSetting = null;
|
||||||
|
this.builder.sentinel = `# ${Math.random()}`;
|
||||||
|
this.builder.state = 'init';
|
||||||
|
this.writeToOutput('<br># Building AutoComplete Cache ... ');
|
||||||
|
this.sendLine(this.builder.sentinel);
|
||||||
|
$(this).trigger('build:start');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CliAutoComplete.builderParseLine = function(line) {
|
||||||
|
const cache = this.cache;
|
||||||
|
const builder = this.builder;
|
||||||
|
|
||||||
|
this._builderWatchdogTouch();
|
||||||
|
|
||||||
|
if (line.indexOf(builder.sentinel) !== -1) {
|
||||||
|
// got sentinel
|
||||||
|
const command = builder.commandSequence.shift();
|
||||||
|
|
||||||
|
if (command && this.configEnabled) {
|
||||||
|
// next state
|
||||||
|
builder.state = `parse-${command}`;
|
||||||
|
this.sendLine(command);
|
||||||
|
this.sendLine(builder.sentinel);
|
||||||
|
} else {
|
||||||
|
// done
|
||||||
|
this._builderWatchdogStop();
|
||||||
|
|
||||||
|
if (!this.configEnabled) {
|
||||||
|
// disabled while we were building
|
||||||
|
this.writeToOutput('Cancelled!<br># ');
|
||||||
|
this.cleanup();
|
||||||
|
} else {
|
||||||
|
cache.settings.sort();
|
||||||
|
cache.commands.sort();
|
||||||
|
cache.feature.sort();
|
||||||
|
cache.beeper.sort();
|
||||||
|
cache.resources = Object.keys(cache.resourcesCount).sort();
|
||||||
|
|
||||||
|
this._initTextcomplete();
|
||||||
|
this.writeToOutput('Done!<br># ');
|
||||||
|
builder.state = 'done';
|
||||||
|
}
|
||||||
|
$(this).trigger('build:stop');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (builder.state) {
|
||||||
|
case 'parse-help':
|
||||||
|
const matchHelp = line.match(/^(\w+)/);
|
||||||
|
if (matchHelp) {
|
||||||
|
cache.commands.push(matchHelp[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'parse-dump':
|
||||||
|
const matchDump = line.match(/^resource\s+(\w+)/i);
|
||||||
|
if (matchDump) {
|
||||||
|
const r = matchDump[1].toUpperCase(); // should alread be upper, but to be sure, since we depend on that later
|
||||||
|
cache.resourcesCount[r] = (cache.resourcesCount[r] || 0) + 1;
|
||||||
|
} else {
|
||||||
|
const matchFeatBeep = line.match(/^(feature|beeper)\s+-?(\w+)/i);
|
||||||
|
if (matchFeatBeep) {
|
||||||
|
cache[matchFeatBeep[1].toLowerCase()].push(matchFeatBeep[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'parse-get':
|
||||||
|
const matchGet = line.match(/^(\w+)\s*=/);
|
||||||
|
if (matchGet) {
|
||||||
|
// setting name
|
||||||
|
cache.settings.push(matchGet[1]);
|
||||||
|
builder.currentSetting = matchGet[1].toLowerCase();
|
||||||
|
} else {
|
||||||
|
const matchGetSettings = line.match(/^(.*): (.*)/);
|
||||||
|
if (matchGetSettings !== null && builder.currentSetting) {
|
||||||
|
if (matchGetSettings[1].match(/values/i)) {
|
||||||
|
// Allowed Values
|
||||||
|
cache.settingsAcceptedValues[builder.currentSetting] = matchGetSettings[2].split(/\s*,\s*/).sort();
|
||||||
|
} else if (matchGetSettings[1].match(/range|length/i)){
|
||||||
|
// "Allowed range" or "Array length", store as string hint
|
||||||
|
cache.settingsAcceptedValues[builder.currentSetting] = matchGetSettings[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes textcomplete with all the autocomplete strategies
|
||||||
|
*/
|
||||||
|
CliAutoComplete._initTextcomplete = function() {
|
||||||
|
let sendOnEnter = false;
|
||||||
|
const self = this;
|
||||||
|
const $textarea = this.$textarea;
|
||||||
|
const cache = self.cache;
|
||||||
|
|
||||||
|
let savedMouseoverItemHandler = null;
|
||||||
|
|
||||||
|
// helper functions
|
||||||
|
const highlighter = function(anywhere) {
|
||||||
|
return function(value, term) {
|
||||||
|
const anywherePrefix = anywhere ? '': '^';
|
||||||
|
const termValue = value.replace(new RegExp(`${anywherePrefix}(${term})`, 'gi'), '<b>$1</b>');
|
||||||
|
return term ? termValue : value;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const highlighterAnywhere = highlighter(true);
|
||||||
|
const highlighterPrefix = highlighter(false);
|
||||||
|
|
||||||
|
const searcher = function(term, callback, array, minChars, matchPrefix) {
|
||||||
|
const res = [];
|
||||||
|
|
||||||
|
if ((minChars !== false && term.length >= minChars) || self.forceOpen || self.isOpen()) {
|
||||||
|
term = term.toLowerCase();
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
const v = array[i].toLowerCase();
|
||||||
|
if (matchPrefix && v.startsWith(term) || !matchPrefix && v.indexOf(term) !== -1) {
|
||||||
|
res.push(array[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(res);
|
||||||
|
|
||||||
|
if (self.forceOpen && res.length === 1) {
|
||||||
|
// hacky: if we came here because of Tab and there's only one match
|
||||||
|
// trigger Tab again, so that textcomplete should immediately select the only result
|
||||||
|
// instead of showing the menu
|
||||||
|
$textarea.trigger($.Event('keydown', {keyCode:9}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const contexter = function(text) {
|
||||||
|
const val = $textarea.val();
|
||||||
|
if (val.length === text.length || val[text.length].match(/\s/)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // do not show autocomplete if in the middle of a word
|
||||||
|
};
|
||||||
|
|
||||||
|
const basicReplacer = function(value) {
|
||||||
|
return `$1${value} `;
|
||||||
|
};
|
||||||
|
// end helper functions
|
||||||
|
|
||||||
|
// init textcomplete
|
||||||
|
$textarea.textcomplete([],
|
||||||
|
{
|
||||||
|
maxCount: 10000,
|
||||||
|
debounce: 0,
|
||||||
|
className: 'cli-textcomplete-dropdown',
|
||||||
|
placement: 'top',
|
||||||
|
onKeydown: function(e) {
|
||||||
|
// some strategies may set sendOnEnter only at the replace stage, thus we call with timeout
|
||||||
|
// since this handler [onKeydown] is triggered before replace()
|
||||||
|
if (e.which === 13) {
|
||||||
|
setTimeout(function() {
|
||||||
|
if (sendOnEnter) {
|
||||||
|
// fake "enter" to run the textarea's handler
|
||||||
|
$textarea.trigger($.Event('keypress', {which:13}));
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.on('textComplete:show', function() {
|
||||||
|
/**
|
||||||
|
* The purpose of this code is to disable initially the `mouseover` menu item handler.
|
||||||
|
* Normally, when the menu pops up, if the mouse cursor is in the same area,
|
||||||
|
* the `mouseover` event triggers immediately and activates the item under
|
||||||
|
* the cursor. This might be undesirable when using the keyboard.
|
||||||
|
*
|
||||||
|
* Here we save the original `mouseover` handler and remove it on popup show.
|
||||||
|
* Then add `mousemove` handler. If the mouse moves we consider that mouse interaction
|
||||||
|
* is desired so we reenable the `mouseover` handler
|
||||||
|
*/
|
||||||
|
|
||||||
|
const textCompleteDropDownElement = $('.textcomplete-dropdown');
|
||||||
|
|
||||||
|
if (!savedMouseoverItemHandler) {
|
||||||
|
// save the original 'mouseover' handeler
|
||||||
|
try {
|
||||||
|
savedMouseoverItemHandler = $._data(textCompleteDropDownElement[0], 'events').mouseover[0].handler;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savedMouseoverItemHandler) {
|
||||||
|
textCompleteDropDownElement
|
||||||
|
.off('mouseover') // initially disable it
|
||||||
|
.off('mousemove') // avoid `mousemove` accumulation if previous show did not trigger `mousemove`
|
||||||
|
.on('mousemove', '.textcomplete-item', function(e) {
|
||||||
|
// the mouse has moved so reenable `mouseover`
|
||||||
|
$(this).parent()
|
||||||
|
.off('mousemove')
|
||||||
|
.on('mouseover', '.textcomplete-item', savedMouseoverItemHandler);
|
||||||
|
|
||||||
|
// trigger the mouseover handler to select the item under the cursor
|
||||||
|
savedMouseoverItemHandler(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// textcomplete autocomplete strategies
|
||||||
|
|
||||||
|
// strategy builder helper
|
||||||
|
const strategy = function(s) {
|
||||||
|
return $.extend({
|
||||||
|
template: highlighterAnywhere,
|
||||||
|
replace: basicReplacer,
|
||||||
|
context: contexter,
|
||||||
|
index: 2,
|
||||||
|
}, s);
|
||||||
|
};
|
||||||
|
|
||||||
|
$textarea.textcomplete('register', [
|
||||||
|
strategy({ // "command"
|
||||||
|
match: /^(\s*)(\w*)$/,
|
||||||
|
search: function(term, callback) {
|
||||||
|
sendOnEnter = false;
|
||||||
|
searcher(term, callback, cache.commands, false, true);
|
||||||
|
},
|
||||||
|
template: highlighterPrefix,
|
||||||
|
}),
|
||||||
|
|
||||||
|
strategy({ // "get"
|
||||||
|
match: /^(\s*get\s+)(\w*)$/i,
|
||||||
|
search: function(term, callback) {
|
||||||
|
sendOnEnter = true;
|
||||||
|
searcher(term, function(arr) {
|
||||||
|
if (term.length > 0 && arr.length > 1) {
|
||||||
|
// prepend the uncompleted term in the popup
|
||||||
|
arr = [term].concat(arr);
|
||||||
|
}
|
||||||
|
callback(arr);
|
||||||
|
}, cache.settings, 3);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
strategy({ // "set"
|
||||||
|
match: /^(\s*set\s+)(\w*)$/i,
|
||||||
|
search: function(term, callback) {
|
||||||
|
sendOnEnter = false;
|
||||||
|
searcher(term, callback, cache.settings, 3);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
strategy({ // "set ="
|
||||||
|
match: /^(\s*set\s+\w*\s*)$/i,
|
||||||
|
search: function(term, callback) {
|
||||||
|
sendOnEnter = false;
|
||||||
|
searcher('', callback, ['='], false);
|
||||||
|
},
|
||||||
|
replace: function(value) {
|
||||||
|
self.openLater();
|
||||||
|
return basicReplacer(value);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
strategy({ // "set with value"
|
||||||
|
match: /^(\s*set\s+(\w+))\s*=\s*(.*)$/i,
|
||||||
|
search: function(term, callback, match) {
|
||||||
|
const arr = [];
|
||||||
|
const settingName = match[2].toLowerCase();
|
||||||
|
this.isSettingValueArray = false;
|
||||||
|
this.value = match[3];
|
||||||
|
sendOnEnter = !!term;
|
||||||
|
|
||||||
|
if (settingName in cache.settingsAcceptedValues) {
|
||||||
|
const val = cache.settingsAcceptedValues[settingName];
|
||||||
|
|
||||||
|
if (Array.isArray(val)) {
|
||||||
|
// setting uses lookup strings
|
||||||
|
this.isSettingValueArray = true;
|
||||||
|
sendOnEnter = true;
|
||||||
|
searcher(term, callback, val, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the settings uses a numeric value.
|
||||||
|
// Here we use a little trick - we use the autocomplete
|
||||||
|
// list as kind of a tooltip to display the Accepted Range hint
|
||||||
|
arr.push(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(arr);
|
||||||
|
},
|
||||||
|
replace: function (value) {
|
||||||
|
if (!this.isSettingValueArray) {
|
||||||
|
// `value` is the tooltip text, so use the saved match
|
||||||
|
value = this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `$1 = ${value}`; // cosmetic - make sure we have spaces around the `=`
|
||||||
|
},
|
||||||
|
index: 3,
|
||||||
|
isSettingValueArray: false,
|
||||||
|
}),
|
||||||
|
|
||||||
|
strategy({ // "resource"
|
||||||
|
match: /^(\s*resource\s+)(\w*)$/i,
|
||||||
|
search: function(term, callback) {
|
||||||
|
sendOnEnter = false;
|
||||||
|
let arr = cache.resources;
|
||||||
|
arr = ['show'].concat(arr);
|
||||||
|
searcher(term, callback, arr, 1);
|
||||||
|
},
|
||||||
|
replace: function(value) {
|
||||||
|
if (value in cache.resourcesCount) {
|
||||||
|
self.openLater();
|
||||||
|
} else if (value === 'list' || value === 'show') {
|
||||||
|
sendOnEnter = true;
|
||||||
|
}
|
||||||
|
return basicReplacer(value);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
strategy({ // "resource index"
|
||||||
|
match: /^(\s*resource\s+(\w+)\s+)(\d*)$/i,
|
||||||
|
search: function(term, callback, match) {
|
||||||
|
sendOnEnter = false;
|
||||||
|
this.savedTerm = term;
|
||||||
|
callback([`<1-${cache.resourcesCount[match[2].toUpperCase()]}>`]);
|
||||||
|
},
|
||||||
|
replace: function() {
|
||||||
|
if (this.savedTerm) {
|
||||||
|
self.openLater();
|
||||||
|
return '$1$3 ';
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
context: function(text) {
|
||||||
|
const matchResource = text.match(/^\s*resource\s+(\w+)\s/i);
|
||||||
|
// use this strategy only for resources with more than one index
|
||||||
|
if (matchResource && (cache.resourcesCount[matchResource[1].toUpperCase()] || 0) > 1 ) {
|
||||||
|
return contexter(text);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
index: 3,
|
||||||
|
savedTerm: null,
|
||||||
|
}),
|
||||||
|
|
||||||
|
strategy({ // "resource pin"
|
||||||
|
match: /^(\s*resource\s+\w+\s+(\d*\s+)?)(\w*)$/i,
|
||||||
|
search: function(term, callback) {
|
||||||
|
sendOnEnter = !!term;
|
||||||
|
if (term) {
|
||||||
|
if ('none'.startsWith(term)) {
|
||||||
|
callback(['none']);
|
||||||
|
} else {
|
||||||
|
callback(['<pin>']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(['<pin>', 'none']);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: function(value, term) {
|
||||||
|
if (value === 'none') {
|
||||||
|
return highlighterPrefix(value, term);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
replace: function(value) {
|
||||||
|
if (value === 'none') {
|
||||||
|
sendOnEnter = true;
|
||||||
|
return '$1none ';
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
context: function(text) {
|
||||||
|
const m = text.match(/^\s*resource\s+(\w+)\s+(\d+\s)?/i);
|
||||||
|
if (m) {
|
||||||
|
// show pin/none for resources having only one index (it's not needed at the commend line)
|
||||||
|
// OR having more than one index and the index is supplied at the command line
|
||||||
|
const count = cache.resourcesCount[m[1].toUpperCase()] || 0;
|
||||||
|
if (count && (m[2] || count === 1)) {
|
||||||
|
return contexter(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
index: 3,
|
||||||
|
}),
|
||||||
|
|
||||||
|
strategy({ // "feature" and "beeper"
|
||||||
|
match: /^(\s*(feature|beeper)\s+(-?))(\w*)$/i,
|
||||||
|
search: function(term, callback, match) {
|
||||||
|
sendOnEnter = !!term;
|
||||||
|
let arr = cache[match[2].toLowerCase()];
|
||||||
|
if (!match[3]) {
|
||||||
|
arr = ['-', 'list'].concat(arr);
|
||||||
|
}
|
||||||
|
searcher(term, callback, arr, 1);
|
||||||
|
},
|
||||||
|
replace: function(value) {
|
||||||
|
if (value === '-') {
|
||||||
|
self.openLater(true);
|
||||||
|
return '$1-';
|
||||||
|
}
|
||||||
|
return basicReplacer(value);
|
||||||
|
},
|
||||||
|
index: 4,
|
||||||
|
}),
|
||||||
|
|
||||||
|
]);
|
||||||
|
|
||||||
|
$textarea.textcomplete('register', [
|
||||||
|
strategy({ // "resource show all", from BF 4.0.0 onwards
|
||||||
|
match: /^(\s*resource\s+show\s+)(\w*)$/i,
|
||||||
|
search: function(term, callback) {
|
||||||
|
sendOnEnter = true;
|
||||||
|
searcher(term, callback, ['all'], 1, true);
|
||||||
|
},
|
||||||
|
template: highlighterPrefix,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// diff command
|
||||||
|
const diffArgs1 = ["master", "profile", "rates", "all"];
|
||||||
|
const diffArgs2 = [];
|
||||||
|
|
||||||
|
// above 3.4.0
|
||||||
|
diffArgs2.push("defaults");
|
||||||
|
diffArgs1.push("hardware");
|
||||||
|
diffArgs2.push("bare");
|
||||||
|
|
||||||
|
diffArgs1.sort();
|
||||||
|
diffArgs2.sort();
|
||||||
|
|
||||||
|
$textarea.textcomplete('register', [
|
||||||
|
strategy({ // "diff arg1"
|
||||||
|
match: /^(\s*diff\s+)(\w*)$/i,
|
||||||
|
search: function(term, callback) {
|
||||||
|
sendOnEnter = true;
|
||||||
|
searcher(term, callback, diffArgs1, 1, true);
|
||||||
|
},
|
||||||
|
template: highlighterPrefix,
|
||||||
|
}),
|
||||||
|
|
||||||
|
strategy({ // "diff arg1 arg2"
|
||||||
|
match: /^(\s*diff\s+\w+\s+)(\w*)$/i,
|
||||||
|
search: function(term, callback) {
|
||||||
|
sendOnEnter = true;
|
||||||
|
searcher(term, callback, diffArgs2, 1, true);
|
||||||
|
},
|
||||||
|
template: highlighterPrefix,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
};
|
|
@ -5,7 +5,7 @@ var appUpdater = appUpdater || {};
|
||||||
appUpdater.checkRelease = function (currVersion) {
|
appUpdater.checkRelease = function (currVersion) {
|
||||||
var modalStart;
|
var modalStart;
|
||||||
$.get('https://api.github.com/repos/iNavFlight/inav-configurator/releases', function (releaseData) {
|
$.get('https://api.github.com/repos/iNavFlight/inav-configurator/releases', function (releaseData) {
|
||||||
GUI.log('Loaded release information from GitHub.');
|
GUI.log(chrome.i18n.getMessage('loadedReleaseInfo'));
|
||||||
//Git return sorted list, 0 - last release
|
//Git return sorted list, 0 - last release
|
||||||
|
|
||||||
let newVersion = releaseData[0].tag_name;
|
let newVersion = releaseData[0].tag_name;
|
||||||
|
@ -15,7 +15,7 @@ appUpdater.checkRelease = function (currVersion) {
|
||||||
GUI.log(newVersion, chrome.runtime.getManifest().version);
|
GUI.log(newVersion, chrome.runtime.getManifest().version);
|
||||||
GUI.log(currVersion);
|
GUI.log(currVersion);
|
||||||
|
|
||||||
GUI.log('New version available!');
|
GUI.log(chrome.i18n.getMessage('newVersionAvailable'));
|
||||||
modalStart = new jBox('Modal', {
|
modalStart = new jBox('Modal', {
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 200,
|
height: 200,
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
var CONFIGURATOR = {
|
var CONFIGURATOR = {
|
||||||
// all versions are specified and compared using semantic versioning http://semver.org/
|
// all versions are specified and compared using semantic versioning http://semver.org/
|
||||||
'minfirmwareVersionAccepted': '5.0.0',
|
'minfirmwareVersionAccepted': '7.0.0',
|
||||||
'maxFirmwareVersionAccepted': '6.0.0', // Condition is < (lt) so we accept all in 5.x branch
|
'maxFirmwareVersionAccepted': '9.0.0', // Condition is < (lt) so we accept all in 8.x branch
|
||||||
'connectionValid': false,
|
'connectionValid': false,
|
||||||
'connectionValidCliOnly': false,
|
'connectionValidCliOnly': false,
|
||||||
'cliActive': false,
|
'cliActive': false,
|
||||||
|
|
|
@ -102,10 +102,13 @@ helper.defaultsDialog = (function (data) {
|
||||||
};
|
};
|
||||||
|
|
||||||
privateScope.saveAndReboot = function () {
|
privateScope.saveAndReboot = function () {
|
||||||
|
|
||||||
GUI.tab_switch_cleanup(function () {
|
GUI.tab_switch_cleanup(function () {
|
||||||
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, function () {
|
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, function () {
|
||||||
//noinspection JSUnresolvedVariable
|
//noinspection JSUnresolvedVariable
|
||||||
savingDefaultsModal.close();
|
if (typeof savingDefaultsModal !== 'undefined') {
|
||||||
|
savingDefaultsModal.close();
|
||||||
|
}
|
||||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||||
GUI.handleReconnect();
|
GUI.handleReconnect();
|
||||||
});
|
});
|
||||||
|
@ -132,39 +135,96 @@ helper.defaultsDialog = (function (data) {
|
||||||
};
|
};
|
||||||
|
|
||||||
privateScope.setSettings = function (selectedDefaultPreset) {
|
privateScope.setSettings = function (selectedDefaultPreset) {
|
||||||
//Save analytics
|
var currentControlProfile = parseInt($("#profilechange").val());
|
||||||
googleAnalytics.sendEvent('Setting', 'Defaults', selectedDefaultPreset.title);
|
var currentBatteryProfile = parseInt($("#batteryprofilechange").val());
|
||||||
Promise.mapSeries(selectedDefaultPreset.settings, function (input, ii) {
|
|
||||||
return mspHelper.getSetting(input.key);
|
|
||||||
}).then(function () {
|
|
||||||
Promise.mapSeries(selectedDefaultPreset.settings, function (input, ii) {
|
|
||||||
return mspHelper.setSetting(input.key, input.value);
|
|
||||||
}).then(function () {
|
|
||||||
|
|
||||||
// If default preset is associated to a mixer, apply the mixer as well
|
var controlProfileSettings = [];
|
||||||
if (selectedDefaultPreset.mixerToApply) {
|
var batterySettings = [];
|
||||||
let currentMixerPreset = helper.mixer.getById(selectedDefaultPreset.mixerToApply);
|
var miscSettings = [];
|
||||||
|
|
||||||
helper.mixer.loadServoRules(currentMixerPreset);
|
selectedDefaultPreset.settings.forEach(input => {
|
||||||
helper.mixer.loadMotorRules(currentMixerPreset);
|
if (FC.isControlProfileParameter(input.key)) {
|
||||||
|
controlProfileSettings.push(input);
|
||||||
SERVO_RULES.cleanup();
|
} else if (FC.isBatteryProfileParameter(input.key)) {
|
||||||
SERVO_RULES.inflate();
|
batterySettings.push(input);
|
||||||
MOTOR_RULES.cleanup();
|
} else {
|
||||||
MOTOR_RULES.inflate();
|
miscSettings.push(input);
|
||||||
|
}
|
||||||
mspHelper.sendServoMixer(function () {
|
|
||||||
mspHelper.sendMotorMixer(function () {
|
|
||||||
privateScope.finalize(selectedDefaultPreset);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
privateScope.finalize(selectedDefaultPreset);
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
//Save analytics
|
||||||
|
googleAnalytics.sendEvent('Setting', 'Defaults', selectedDefaultPreset.title);
|
||||||
|
|
||||||
|
var settingsChainer = MSPChainerClass();
|
||||||
|
var chain = [];
|
||||||
|
|
||||||
|
miscSettings.forEach(input => {
|
||||||
|
chain.push(function (callback) {
|
||||||
|
mspHelper.setSetting(input.key, input.value, callback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
for (var i = 0; i < 3; i++ ) {
|
||||||
|
chain.push(function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [i], false, callback);
|
||||||
|
});
|
||||||
|
controlProfileSettings.forEach(input => {
|
||||||
|
chain.push(function (callback) {
|
||||||
|
mspHelper.setSetting(input.key, input.value, callback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < 3; i++ ) {
|
||||||
|
chain.push(function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP2_INAV_SELECT_BATTERY_PROFILE, [i], false, callback);
|
||||||
|
});
|
||||||
|
batterySettings.forEach(input => {
|
||||||
|
chain.push(function (callback) {
|
||||||
|
mspHelper.setSetting(input.key, input.value, callback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Mixers
|
||||||
|
if (selectedDefaultPreset.mixerToApply) {
|
||||||
|
let currentMixerPreset = helper.mixer.getById(selectedDefaultPreset.mixerToApply);
|
||||||
|
|
||||||
|
helper.mixer.loadServoRules(currentMixerPreset);
|
||||||
|
helper.mixer.loadMotorRules(currentMixerPreset);
|
||||||
|
|
||||||
|
MIXER_CONFIG.platformType = currentMixerPreset.platform;
|
||||||
|
MIXER_CONFIG.appliedMixerPreset = selectedDefaultPreset.mixerToApply;
|
||||||
|
MIXER_CONFIG.motorStopOnLow = (currentMixerPreset.motorStopOnLow === true) ? true : false;
|
||||||
|
MIXER_CONFIG.hasFlaps = (currentMixerPreset.hasFlaps === true) ? true : false;
|
||||||
|
|
||||||
|
SERVO_RULES.cleanup();
|
||||||
|
SERVO_RULES.inflate();
|
||||||
|
MOTOR_RULES.cleanup();
|
||||||
|
MOTOR_RULES.inflate();
|
||||||
|
|
||||||
|
chain = chain.concat([
|
||||||
|
mspHelper.saveMixerConfig,
|
||||||
|
mspHelper.sendServoMixer,
|
||||||
|
mspHelper.sendMotorMixer
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.push(function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [currentControlProfile], false, callback);
|
||||||
|
});
|
||||||
|
|
||||||
|
chain.push(function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP2_INAV_SELECT_BATTERY_PROFILE, [currentBatteryProfile], false, callback);
|
||||||
|
});
|
||||||
|
|
||||||
|
settingsChainer.setChain(chain);
|
||||||
|
settingsChainer.setExitPoint(function () {
|
||||||
|
privateScope.finalize(selectedDefaultPreset);
|
||||||
|
});
|
||||||
|
|
||||||
|
settingsChainer.execute();
|
||||||
|
}
|
||||||
|
|
||||||
privateScope.onPresetClick = function (event) {
|
privateScope.onPresetClick = function (event) {
|
||||||
savingDefaultsModal = new jBox('Modal', {
|
savingDefaultsModal = new jBox('Modal', {
|
||||||
|
|
|
@ -2,22 +2,8 @@ var helper = helper || {};
|
||||||
|
|
||||||
helper.defaultsDialogData = [
|
helper.defaultsDialogData = [
|
||||||
{
|
{
|
||||||
"title": 'Test',
|
"title": 'Mini Quad with 3" propellers',
|
||||||
"id": 17,
|
"id": 6,
|
||||||
"notRecommended": false,
|
|
||||||
"reboot": true,
|
|
||||||
"mixerToApply": 3,
|
|
||||||
"wizardPages": ['receiver', 'outputs', 'gps', 'filters', 'pids'],
|
|
||||||
"settings": [
|
|
||||||
{
|
|
||||||
key: "model_preview_type",
|
|
||||||
value: 3
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": 'Mini Quad with 3"-7" propellers',
|
|
||||||
"id": 2,
|
|
||||||
"notRecommended": false,
|
"notRecommended": false,
|
||||||
"reboot": true,
|
"reboot": true,
|
||||||
"mixerToApply": 3,
|
"mixerToApply": 3,
|
||||||
|
@ -43,55 +29,43 @@ helper.defaultsDialogData = [
|
||||||
value: "DSHOT300"
|
value: "DSHOT300"
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
Filtering
|
Ez Tune setup
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
key: "gyro_main_lpf_hz",
|
key: "ez_enabled",
|
||||||
value: 110
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "gyro_main_lpf_type",
|
|
||||||
value: "PT1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "dterm_lpf_hz",
|
|
||||||
value: 110
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "dterm_lpf_type",
|
|
||||||
value: "PT3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "dterm_lpf2_hz",
|
|
||||||
value: 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "dterm_lpf2_type",
|
|
||||||
value: "PT1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "dynamic_gyro_notch_enabled",
|
|
||||||
value: "ON"
|
value: "ON"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "dynamic_gyro_notch_q",
|
key: "ez_filter_hz",
|
||||||
value: 250
|
value: 90
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "dynamic_gyro_notch_min_hz",
|
key: "ez_axis_ratio",
|
||||||
value: 120
|
value: 116
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "setpoint_kalman_enabled",
|
key: "ez_response",
|
||||||
value: "ON"
|
value: 71
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "setpoint_kalman_q",
|
key: "ez_damping",
|
||||||
value: 200
|
value: 103
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "smith_predictor_delay", // Enable Smith Predictor
|
key: "ez_stability",
|
||||||
value: 1.5
|
value: 105
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_aggressiveness",
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_rate",
|
||||||
|
value: 134
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_expo",
|
||||||
|
value: 118
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
Mechanics
|
Mechanics
|
||||||
|
@ -110,11 +84,11 @@ helper.defaultsDialogData = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "d_boost_min",
|
key: "d_boost_min",
|
||||||
value: 0.8
|
value: 1.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "d_boost_max",
|
key: "d_boost_max",
|
||||||
value: 1.2
|
value: 1.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "antigravity_gain",
|
key: "antigravity_gain",
|
||||||
|
@ -125,63 +99,145 @@ helper.defaultsDialogData = [
|
||||||
value: 5
|
value: 5
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
Rates
|
* TPA
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
key: "rc_yaw_expo",
|
key: "tpa_rate",
|
||||||
value: 75
|
value: 20
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "rc_expo",
|
key: "tpa_breakpoint",
|
||||||
value: 75
|
value: 1200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "roll_rate",
|
key: "platform_type",
|
||||||
value: 70
|
value: "MULTIROTOR"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "pitch_rate",
|
key: "applied_defaults",
|
||||||
value: 70
|
value: 6
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "yaw_rate",
|
key: "failsafe_procedure",
|
||||||
value: 60
|
value: "DROP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": 'Mini Quad with 5" propellers',
|
||||||
|
"id": 2,
|
||||||
|
"notRecommended": false,
|
||||||
|
"reboot": true,
|
||||||
|
"mixerToApply": 3,
|
||||||
|
"settings": [
|
||||||
|
{
|
||||||
|
key: "model_preview_type",
|
||||||
|
value: 3
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
PIDs
|
System
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
key: "mc_p_pitch",
|
key: "gyro_hardware_lpf",
|
||||||
value: 44
|
value: "256HZ"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "mc_i_pitch",
|
key: "looptime",
|
||||||
value: 75
|
value: 500
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "mc_d_pitch",
|
key: "motor_pwm_protocol",
|
||||||
value: 25
|
value: "DSHOT300"
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
Ez Tune setup
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
key: "ez_enabled",
|
||||||
|
value: "ON"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "mc_p_roll",
|
key: "ez_filter_hz",
|
||||||
value: 40
|
value: 110
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "mc_i_roll",
|
key: "ez_axis_ratio",
|
||||||
value: 60
|
value: 110
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "mc_d_roll",
|
key: "ez_response",
|
||||||
value: 23
|
value: 92
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "mc_p_yaw",
|
key: "ez_damping",
|
||||||
value: 35
|
value: 108
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "mc_i_yaw",
|
key: "ez_stability",
|
||||||
|
value: 110
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_aggressiveness",
|
||||||
value: 80
|
value: 80
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "ez_rate",
|
||||||
|
value: 134
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_expo",
|
||||||
|
value: 118
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
Dynamic gyro LPF
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
key: "gyro_use_dyn_lpf",
|
||||||
|
value: "ON"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "gyro_dyn_lpf_min_hz",
|
||||||
|
value: 85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "gyro_dyn_lpf_max_hz",
|
||||||
|
value: 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "gyro_dyn_lpf_curve_expo",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
Mechanics
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
key: "airmode_type",
|
||||||
|
value: "THROTTLE_THRESHOLD"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "airmode_throttle_threshold",
|
||||||
|
value: 1150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "mc_iterm_relax",
|
||||||
|
value: "RP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "d_boost_min",
|
||||||
|
value: 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "d_boost_max",
|
||||||
|
value: 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "antigravity_gain",
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "antigravity_accelerator",
|
||||||
|
value: 5
|
||||||
|
},
|
||||||
/*
|
/*
|
||||||
* TPA
|
* TPA
|
||||||
*/
|
*/
|
||||||
|
@ -207,6 +263,127 @@ helper.defaultsDialogData = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": 'Mini Quad with 7" propellers',
|
||||||
|
"id": 5,
|
||||||
|
"notRecommended": false,
|
||||||
|
"reboot": true,
|
||||||
|
"mixerToApply": 3,
|
||||||
|
"settings": [
|
||||||
|
{
|
||||||
|
key: "model_preview_type",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
System
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
key: "gyro_hardware_lpf",
|
||||||
|
value: "256HZ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "looptime",
|
||||||
|
value: 500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "motor_pwm_protocol",
|
||||||
|
value: "DSHOT300"
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
Ez Tune setup
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
key: "ez_enabled",
|
||||||
|
value: "ON"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_filter_hz",
|
||||||
|
value: 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_axis_ratio",
|
||||||
|
value: 110
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_response",
|
||||||
|
value: 101
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_damping",
|
||||||
|
value: 115
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_stability",
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_aggressiveness",
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_rate",
|
||||||
|
value: 134
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "ez_expo",
|
||||||
|
value: 118
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
Mechanics
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
key: "airmode_type",
|
||||||
|
value: "THROTTLE_THRESHOLD"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "airmode_throttle_threshold",
|
||||||
|
value: 1150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "mc_iterm_relax",
|
||||||
|
value: "RPY"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "d_boost_min",
|
||||||
|
value: 0.8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "d_boost_max",
|
||||||
|
value: 1.2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "antigravity_gain",
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "antigravity_accelerator",
|
||||||
|
value: 5
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
* TPA
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
key: "tpa_rate",
|
||||||
|
value: 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "tpa_breakpoint",
|
||||||
|
value: 1200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "platform_type",
|
||||||
|
value: "MULTIROTOR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "applied_defaults",
|
||||||
|
value: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "failsafe_procedure",
|
||||||
|
value: "DROP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": 'Airplane with a Tail',
|
"title": 'Airplane with a Tail',
|
||||||
"notRecommended": false,
|
"notRecommended": false,
|
||||||
|
@ -266,6 +443,10 @@ helper.defaultsDialogData = [
|
||||||
key: "motor_pwm_protocol",
|
key: "motor_pwm_protocol",
|
||||||
value: "STANDARD"
|
value: "STANDARD"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "ahrs_inertia_comp_method",
|
||||||
|
value: "ADAPTIVE"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "throttle_idle",
|
key: "throttle_idle",
|
||||||
value: 5.0
|
value: 5.0
|
||||||
|
@ -292,19 +473,23 @@ helper.defaultsDialogData = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "nav_fw_pos_z_p",
|
key: "nav_fw_pos_z_p",
|
||||||
value: 15
|
value: 25
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "nav_fw_pos_z_d",
|
key: "nav_fw_pos_z_i",
|
||||||
value: 5
|
value: 5
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "nav_fw_pos_z_d",
|
||||||
|
value: 8
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "nav_fw_pos_xy_p",
|
key: "nav_fw_pos_xy_p",
|
||||||
value: 60
|
value: 55
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "fw_turn_assist_pitch_gain",
|
key: "fw_turn_assist_pitch_gain",
|
||||||
value: 0.5
|
value: 0.4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "max_angle_inclination_rll",
|
key: "max_angle_inclination_rll",
|
||||||
|
@ -348,7 +533,7 @@ helper.defaultsDialogData = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "fw_p_yaw",
|
key: "fw_p_yaw",
|
||||||
value: 20
|
value: 50
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "fw_i_yaw",
|
key: "fw_i_yaw",
|
||||||
|
@ -356,19 +541,11 @@ helper.defaultsDialogData = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "fw_d_yaw",
|
key: "fw_d_yaw",
|
||||||
value: 0
|
value: 20
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "fw_ff_yaw",
|
key: "fw_ff_yaw",
|
||||||
value: 100
|
value: 255
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "imu_acc_ignore_rate",
|
|
||||||
value: 9
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "imu_acc_ignore_slope",
|
|
||||||
value: 5
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "airmode_type",
|
key: "airmode_type",
|
||||||
|
@ -391,25 +568,35 @@ helper.defaultsDialogData = [
|
||||||
value: 5000
|
value: 5000
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "failsafe_mission",
|
key: "nav_wp_radius",
|
||||||
value: "ON"
|
value: 800
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "nav_wp_radius",
|
key: "nav_wp_max_safe_distance",
|
||||||
|
value: 500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "nav_fw_launch_max_angle",
|
||||||
|
value: 45
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "nav_fw_launch_motor_delay",
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "nav_fw_launch_max_altitude",
|
||||||
value: 5000
|
value: 5000
|
||||||
},
|
},
|
||||||
],
|
|
||||||
"features": [
|
|
||||||
{
|
{
|
||||||
bit: 4, // Enable MOTOR_STOP
|
key: "nav_fw_launch_climb_angle",
|
||||||
state: true
|
value: 25
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": 'Airplane without a Tail (Wing, Delta, etc)',
|
"title": 'Airplane without a Tail (Wing, Delta, etc)',
|
||||||
"notRecommended": false,
|
"notRecommended": false,
|
||||||
"id": 3,
|
"id": 4,
|
||||||
"reboot": true,
|
"reboot": true,
|
||||||
"mixerToApply": 8,
|
"mixerToApply": 8,
|
||||||
"settings": [
|
"settings": [
|
||||||
|
@ -423,7 +610,7 @@ helper.defaultsDialogData = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "applied_defaults",
|
key: "applied_defaults",
|
||||||
value: 3
|
value: 4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "gyro_hardware_lpf",
|
key: "gyro_hardware_lpf",
|
||||||
|
@ -465,6 +652,10 @@ helper.defaultsDialogData = [
|
||||||
key: "motor_pwm_protocol",
|
key: "motor_pwm_protocol",
|
||||||
value: "STANDARD"
|
value: "STANDARD"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "ahrs_inertia_comp_method",
|
||||||
|
value: "ADAPTIVE"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "throttle_idle",
|
key: "throttle_idle",
|
||||||
value: 5.0
|
value: 5.0
|
||||||
|
@ -491,19 +682,23 @@ helper.defaultsDialogData = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "nav_fw_pos_z_p",
|
key: "nav_fw_pos_z_p",
|
||||||
value: 15
|
value: 35
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "nav_fw_pos_z_d",
|
key: "nav_fw_pos_z_i",
|
||||||
value: 5
|
value: 5
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "nav_fw_pos_z_d",
|
||||||
|
value: 10
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "nav_fw_pos_xy_p",
|
key: "nav_fw_pos_xy_p",
|
||||||
value: 60
|
value: 70
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "fw_turn_assist_pitch_gain",
|
key: "fw_turn_assist_pitch_gain",
|
||||||
value: 0.2
|
value: 0.3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "max_angle_inclination_rll",
|
key: "max_angle_inclination_rll",
|
||||||
|
@ -561,14 +756,6 @@ helper.defaultsDialogData = [
|
||||||
key: "fw_ff_yaw",
|
key: "fw_ff_yaw",
|
||||||
value: 100
|
value: 100
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: "imu_acc_ignore_rate",
|
|
||||||
value: 9
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "imu_acc_ignore_slope",
|
|
||||||
value: 5
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: "airmode_type",
|
key: "airmode_type",
|
||||||
value: "STICK_CENTER_ONCE"
|
value: "STICK_CENTER_ONCE"
|
||||||
|
@ -590,20 +777,30 @@ helper.defaultsDialogData = [
|
||||||
value: 5000
|
value: 5000
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "failsafe_mission",
|
key: "nav_wp_radius",
|
||||||
value: "ON"
|
value: 1000
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "nav_wp_radius",
|
key: "nav_wp_max_safe_distance",
|
||||||
|
value: 500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "nav_fw_launch_max_angle",
|
||||||
|
value: 75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "nav_fw_launch_motor_delay",
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "nav_fw_launch_max_altitude",
|
||||||
value: 5000
|
value: 5000
|
||||||
},
|
},
|
||||||
],
|
|
||||||
"features": [
|
|
||||||
{
|
{
|
||||||
bit: 4, // Enable MOTOR_STOP
|
key: "nav_fw_launch_climb_angle",
|
||||||
state: true
|
value: 25
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": 'Rovers & Boats',
|
"title": 'Rovers & Boats',
|
||||||
|
@ -645,8 +842,8 @@ helper.defaultsDialogData = [
|
||||||
value: "ROVER"
|
value: "ROVER"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "nav_wp_safe_distance",
|
key: "nav_wp_max_safe_distance",
|
||||||
value: 50000
|
value: 500
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "nav_fw_loiter_radius",
|
key: "nav_fw_loiter_radius",
|
||||||
|
|
188
js/fc.js
|
@ -29,6 +29,7 @@ var CONFIG,
|
||||||
MOTOR_DATA,
|
MOTOR_DATA,
|
||||||
SERVO_DATA,
|
SERVO_DATA,
|
||||||
GPS_DATA,
|
GPS_DATA,
|
||||||
|
ADSB_VEHICLES,
|
||||||
MISSION_PLANNER,
|
MISSION_PLANNER,
|
||||||
ANALOG,
|
ANALOG,
|
||||||
ARMING_CONFIG,
|
ARMING_CONFIG,
|
||||||
|
@ -64,7 +65,8 @@ var CONFIG,
|
||||||
SAFEHOMES,
|
SAFEHOMES,
|
||||||
BOARD_ALIGNMENT,
|
BOARD_ALIGNMENT,
|
||||||
CURRENT_METER_CONFIG,
|
CURRENT_METER_CONFIG,
|
||||||
FEATURES;
|
FEATURES,
|
||||||
|
RATE_DYNAMICS;
|
||||||
|
|
||||||
var FC = {
|
var FC = {
|
||||||
restartRequired: false,
|
restartRequired: false,
|
||||||
|
@ -92,8 +94,7 @@ var FC = {
|
||||||
gpsHwStatus: 0,
|
gpsHwStatus: 0,
|
||||||
rangeHwStatus: 0,
|
rangeHwStatus: 0,
|
||||||
speedHwStatus: 0,
|
speedHwStatus: 0,
|
||||||
flowHwStatus: 0,
|
flowHwStatus: 0
|
||||||
imu2HwStatus: 0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SENSOR_CONFIG = {
|
SENSOR_CONFIG = {
|
||||||
|
@ -118,8 +119,9 @@ var FC = {
|
||||||
i2cError: 0,
|
i2cError: 0,
|
||||||
activeSensors: 0,
|
activeSensors: 0,
|
||||||
mode: [],
|
mode: [],
|
||||||
profile: 0,
|
mixer_profile: -1,
|
||||||
battery_profile: 0,
|
profile: -1,
|
||||||
|
battery_profile: -1,
|
||||||
uid: [0, 0, 0],
|
uid: [0, 0, 0],
|
||||||
accelerometerTrims: [0, 0],
|
accelerometerTrims: [0, 0],
|
||||||
armingFlags: 0,
|
armingFlags: 0,
|
||||||
|
@ -196,6 +198,7 @@ var FC = {
|
||||||
MIXER_CONFIG = {
|
MIXER_CONFIG = {
|
||||||
yawMotorDirection: 0,
|
yawMotorDirection: 0,
|
||||||
yawJumpPreventionLimit: 0,
|
yawJumpPreventionLimit: 0,
|
||||||
|
motorStopOnLow: false,
|
||||||
platformType: -1,
|
platformType: -1,
|
||||||
hasFlaps: false,
|
hasFlaps: false,
|
||||||
appliedMixerPreset: -1,
|
appliedMixerPreset: -1,
|
||||||
|
@ -249,6 +252,12 @@ var FC = {
|
||||||
packetCount: 0
|
packetCount: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ADSB_VEHICLES = {
|
||||||
|
vehiclesCount: 0,
|
||||||
|
callsignLength: 0,
|
||||||
|
vehicles: []
|
||||||
|
};
|
||||||
|
|
||||||
MISSION_PLANNER = new WaypointCollection();
|
MISSION_PLANNER = new WaypointCollection();
|
||||||
|
|
||||||
ANALOG = {
|
ANALOG = {
|
||||||
|
@ -541,6 +550,27 @@ var FC = {
|
||||||
SETTINGS = {};
|
SETTINGS = {};
|
||||||
|
|
||||||
SAFEHOMES = new SafehomeCollection();
|
SAFEHOMES = new SafehomeCollection();
|
||||||
|
|
||||||
|
RATE_DYNAMICS = {
|
||||||
|
sensitivityCenter: null,
|
||||||
|
sensitivityEnd: null,
|
||||||
|
correctionCenter: null,
|
||||||
|
correctionEnd: null,
|
||||||
|
weightCenter: null,
|
||||||
|
weightEnd: null
|
||||||
|
};
|
||||||
|
|
||||||
|
EZ_TUNE = {
|
||||||
|
enabled: null,
|
||||||
|
filterHz: null,
|
||||||
|
axisRatio: null,
|
||||||
|
response: null,
|
||||||
|
damping: null,
|
||||||
|
stability: null,
|
||||||
|
aggressiveness: null,
|
||||||
|
rate: null,
|
||||||
|
expo: null
|
||||||
|
};
|
||||||
},
|
},
|
||||||
getOutputUsages: function() {
|
getOutputUsages: function() {
|
||||||
return {
|
return {
|
||||||
|
@ -555,7 +585,6 @@ var FC = {
|
||||||
getFeatures: function () {
|
getFeatures: function () {
|
||||||
var features = [
|
var features = [
|
||||||
{bit: 1, group: 'batteryVoltage', name: 'VBAT'},
|
{bit: 1, group: 'batteryVoltage', name: 'VBAT'},
|
||||||
{bit: 4, group: 'other', name: 'MOTOR_STOP'},
|
|
||||||
{bit: 6, group: 'other', name: 'SOFTSERIAL', haveTip: true, showNameInTip: true},
|
{bit: 6, group: 'other', name: 'SOFTSERIAL', haveTip: true, showNameInTip: true},
|
||||||
{bit: 7, group: 'other', name: 'GPS', haveTip: true},
|
{bit: 7, group: 'other', name: 'GPS', haveTip: true},
|
||||||
{bit: 10, group: 'other', name: 'TELEMETRY', showNameInTip: true},
|
{bit: 10, group: 'other', name: 'TELEMETRY', showNameInTip: true},
|
||||||
|
@ -594,13 +623,10 @@ var FC = {
|
||||||
},
|
},
|
||||||
getGpsProtocols: function () {
|
getGpsProtocols: function () {
|
||||||
return [
|
return [
|
||||||
'NMEA',
|
|
||||||
'UBLOX',
|
'UBLOX',
|
||||||
'I2C-NAV',
|
|
||||||
'DJI NAZA',
|
|
||||||
'UBLOX7',
|
'UBLOX7',
|
||||||
'MTK',
|
'MSP',
|
||||||
'MSP'
|
'FAKE'
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
getGpsBaudRates: function () {
|
getGpsBaudRates: function () {
|
||||||
|
@ -619,6 +645,7 @@ var FC = {
|
||||||
'North American WAAS',
|
'North American WAAS',
|
||||||
'Japanese MSAS',
|
'Japanese MSAS',
|
||||||
'Indian GAGAN',
|
'Indian GAGAN',
|
||||||
|
'SouthPAN (AU/NZ)',
|
||||||
'Disabled'
|
'Disabled'
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
@ -767,6 +794,24 @@ var FC = {
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
},
|
},
|
||||||
|
getAccelerometerCalibrated: function () {
|
||||||
|
var calibrated = true;
|
||||||
|
var flagNames = FC.getArmingFlags();
|
||||||
|
|
||||||
|
if (CALIBRATION_DATA.accGain.X === 4096 && CALIBRATION_DATA.accGain.Y === 4096 && CALIBRATION_DATA.accGain.Z === 4096 &&
|
||||||
|
CALIBRATION_DATA.accZero.X === 0 && CALIBRATION_DATA.accZero.Y === 0 && CALIBRATION_DATA.accZero.Z === 0
|
||||||
|
) {
|
||||||
|
calibrated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((calibrated) && flagNames.hasOwnProperty(13)) {
|
||||||
|
if (bit_check(CONFIG.armingFlags, 13)) {
|
||||||
|
calibrated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return calibrated;
|
||||||
|
},
|
||||||
getUserControlMode: function () {
|
getUserControlMode: function () {
|
||||||
return [
|
return [
|
||||||
"Attitude",
|
"Attitude",
|
||||||
|
@ -865,6 +910,7 @@ var FC = {
|
||||||
'GVAR 5', // 35
|
'GVAR 5', // 35
|
||||||
'GVAR 6', // 36
|
'GVAR 6', // 36
|
||||||
'GVAR 7', // 37
|
'GVAR 7', // 37
|
||||||
|
'Mixer Transition', // 38
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
getServoMixInputName: function (input) {
|
getServoMixInputName: function (input) {
|
||||||
|
@ -892,19 +938,19 @@ var FC = {
|
||||||
output: "boolean"
|
output: "boolean"
|
||||||
},
|
},
|
||||||
1: {
|
1: {
|
||||||
name: "Equal",
|
name: "Equal (A = B)",
|
||||||
operandType: "Comparison",
|
operandType: "Comparison",
|
||||||
hasOperand: [true, true],
|
hasOperand: [true, true],
|
||||||
output: "boolean"
|
output: "boolean"
|
||||||
},
|
},
|
||||||
2: {
|
2: {
|
||||||
name: "Greater Than",
|
name: "Greater Than (A > B)",
|
||||||
operandType: "Comparison",
|
operandType: "Comparison",
|
||||||
hasOperand: [true, true],
|
hasOperand: [true, true],
|
||||||
output: "boolean"
|
output: "boolean"
|
||||||
},
|
},
|
||||||
3: {
|
3: {
|
||||||
name: "Lower Than",
|
name: "Lower Than (A < B)",
|
||||||
operandType: "Comparison",
|
operandType: "Comparison",
|
||||||
hasOperand: [true, true],
|
hasOperand: [true, true],
|
||||||
output: "boolean"
|
output: "boolean"
|
||||||
|
@ -1162,6 +1208,48 @@ var FC = {
|
||||||
hasOperand: [true, true],
|
hasOperand: [true, true],
|
||||||
output: "boolean"
|
output: "boolean"
|
||||||
},
|
},
|
||||||
|
47: {
|
||||||
|
name: "Edge",
|
||||||
|
operandType: "Logic Switches",
|
||||||
|
hasOperand: [true, true],
|
||||||
|
output: "boolean"
|
||||||
|
},
|
||||||
|
48: {
|
||||||
|
name: "Delay",
|
||||||
|
operandType: "Logic Switches",
|
||||||
|
hasOperand: [true, true],
|
||||||
|
output: "boolean"
|
||||||
|
},
|
||||||
|
49: {
|
||||||
|
name: "Timer",
|
||||||
|
operandType: "Logic Switches",
|
||||||
|
hasOperand: [true, true],
|
||||||
|
output: "boolean"
|
||||||
|
},
|
||||||
|
50: {
|
||||||
|
name: "Delta (|A| >= B)",
|
||||||
|
operandType: "Comparison",
|
||||||
|
hasOperand: [true, true],
|
||||||
|
output: "boolean"
|
||||||
|
},
|
||||||
|
51: {
|
||||||
|
name: "Approx Equals (A ~ B)",
|
||||||
|
operandType: "Comparison",
|
||||||
|
hasOperand: [true, true],
|
||||||
|
output: "boolean"
|
||||||
|
},
|
||||||
|
52: {
|
||||||
|
name: "LED Pin PWM",
|
||||||
|
operandType: "Set Flight Parameter",
|
||||||
|
hasOperand: [true, false],
|
||||||
|
output: "raw"
|
||||||
|
},
|
||||||
|
54: {
|
||||||
|
name: "Mag calibration",
|
||||||
|
operandType: "Set Flight Parameter",
|
||||||
|
hasOperand: [false, false],
|
||||||
|
output: "boolean"
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getOperandTypes: function () {
|
getOperandTypes: function () {
|
||||||
|
@ -1208,24 +1296,24 @@ var FC = {
|
||||||
20: "Is Controlling Position",
|
20: "Is Controlling Position",
|
||||||
21: "Is Emergency Landing",
|
21: "Is Emergency Landing",
|
||||||
22: "Is RTH",
|
22: "Is RTH",
|
||||||
23: "Is WP",
|
23: "Is Landing",
|
||||||
24: "Is Landing",
|
24: "Is Failsafe",
|
||||||
25: "Is Failsafe",
|
25: "Stabilized Roll",
|
||||||
26: "Stabilized Roll",
|
26: "Stabilized Pitch",
|
||||||
27: "Stabilized Pitch",
|
27: "Stabilized Yaw",
|
||||||
28: "Stabilized Yaw",
|
28: "3D home distance [m]",
|
||||||
29: "Current Waypoint Index",
|
29: "CRSF LQ",
|
||||||
30: "Current Waypoint Action",
|
30: "CRSF SNR",
|
||||||
31: "3D home distance [m]",
|
31: "GPS Valid Fix",
|
||||||
32: "CRSF LQ",
|
32: "Loiter Radius [cm]",
|
||||||
33: "CRSF SNR",
|
33: "Active PIDProfile",
|
||||||
34: "GPS Valid Fix",
|
34: "Battery cells",
|
||||||
35: "Loiter Radius [cm]",
|
35: "AGL status [0/1]",
|
||||||
36: "Active Profile",
|
36: "AGL [cm]",
|
||||||
37: "Battery cells",
|
37: "Rangefinder [cm]",
|
||||||
38: "AGL status [0/1]",
|
38: "Active MixerProfile",
|
||||||
39: "AGL [cm]",
|
39: "MixerTransition Active",
|
||||||
40: "Rangefinder [cm]",
|
40: "Yaw [deg]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
3: {
|
3: {
|
||||||
|
@ -1243,13 +1331,18 @@ var FC = {
|
||||||
7: "Horizon",
|
7: "Horizon",
|
||||||
8: "Air",
|
8: "Air",
|
||||||
9: "USER 1",
|
9: "USER 1",
|
||||||
10: "USER 2"
|
10: "USER 2",
|
||||||
|
11: "Course Hold",
|
||||||
|
12: "USER 3",
|
||||||
|
13: "USER 4",
|
||||||
|
14: "Acro",
|
||||||
|
15: "Waypoint Mission",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
4: {
|
4: {
|
||||||
name: "Logic Condition",
|
name: "Logic Condition",
|
||||||
type: "range",
|
type: "range",
|
||||||
range: [0, 31],
|
range: [0, (LOGIC_CONDITIONS.getMaxLogicConditionCount()-1)],
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
5: {
|
5: {
|
||||||
|
@ -1263,7 +1356,28 @@ var FC = {
|
||||||
type: "range",
|
type: "range",
|
||||||
range: [0, 3],
|
range: [0, 3],
|
||||||
default: 0
|
default: 0
|
||||||
}
|
},
|
||||||
|
7: {
|
||||||
|
name: "Waypoints",
|
||||||
|
type: "dictionary",
|
||||||
|
default: 0,
|
||||||
|
values: {
|
||||||
|
0: "Is WP",
|
||||||
|
1: "Current Waypoint Index",
|
||||||
|
2: "Current Waypoint Action",
|
||||||
|
3: "Next Waypoint Action",
|
||||||
|
4: "Distance to next Waypoint [m]",
|
||||||
|
5: "Distance from last Waypoint [m]",
|
||||||
|
6: "Current WP has User Action 1",
|
||||||
|
7: "Current WP has User Action 2",
|
||||||
|
8: "Current WP has User Action 3",
|
||||||
|
9: "Current WP has User Action 4",
|
||||||
|
10: "Next WP has User Action 1",
|
||||||
|
11: "Next WP has User Action 2",
|
||||||
|
12: "Next WP has User Action 3",
|
||||||
|
13: "Next WP has User Action 4",
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getBatteryProfileParameters: function () {
|
getBatteryProfileParameters: function () {
|
||||||
|
@ -1282,7 +1396,6 @@ var FC = {
|
||||||
'throttle_idle',
|
'throttle_idle',
|
||||||
'turtle_mode_power_factor',
|
'turtle_mode_power_factor',
|
||||||
'failsafe_throttle',
|
'failsafe_throttle',
|
||||||
'fw_min_throttle_down_pitch',
|
|
||||||
'nav_mc_hover_thr',
|
'nav_mc_hover_thr',
|
||||||
'nav_fw_cruise_thr',
|
'nav_fw_cruise_thr',
|
||||||
'nav_fw_min_thr',
|
'nav_fw_min_thr',
|
||||||
|
@ -1339,11 +1452,8 @@ var FC = {
|
||||||
'max_angle_inclination_pit',
|
'max_angle_inclination_pit',
|
||||||
'dterm_lpf_hz',
|
'dterm_lpf_hz',
|
||||||
'dterm_lpf_type',
|
'dterm_lpf_type',
|
||||||
'dterm_lpf2_hz',
|
|
||||||
'dterm_lpf2_type',
|
|
||||||
'yaw_lpf_hz',
|
'yaw_lpf_hz',
|
||||||
'fw_iterm_throw_limit',
|
'fw_iterm_throw_limit',
|
||||||
'fw_loiter_direction',
|
|
||||||
'fw_reference_airspeed',
|
'fw_reference_airspeed',
|
||||||
'fw_turn_assist_yaw_gain',
|
'fw_turn_assist_yaw_gain',
|
||||||
'fw_turn_assist_pitch_gain',
|
'fw_turn_assist_pitch_gain',
|
||||||
|
|
187
js/gui.js
|
@ -14,6 +14,7 @@ var GUI_control = function () {
|
||||||
'landing',
|
'landing',
|
||||||
'firmware_flasher',
|
'firmware_flasher',
|
||||||
'mission_control',
|
'mission_control',
|
||||||
|
'sitl',
|
||||||
'help'
|
'help'
|
||||||
];
|
];
|
||||||
this.defaultAllowedTabsWhenConnected = [
|
this.defaultAllowedTabsWhenConnected = [
|
||||||
|
@ -40,7 +41,8 @@ var GUI_control = function () {
|
||||||
'advanced_tuning',
|
'advanced_tuning',
|
||||||
'mission_control',
|
'mission_control',
|
||||||
'mixer',
|
'mixer',
|
||||||
'programming'
|
'programming',
|
||||||
|
'ez_tune'
|
||||||
];
|
];
|
||||||
this.allowedTabs = this.defaultAllowedTabsWhenDisconnected;
|
this.allowedTabs = this.defaultAllowedTabsWhenDisconnected;
|
||||||
|
|
||||||
|
@ -51,6 +53,17 @@ var GUI_control = function () {
|
||||||
else if (navigator.appVersion.indexOf("Linux") != -1) this.operating_system = "Linux";
|
else if (navigator.appVersion.indexOf("Linux") != -1) this.operating_system = "Linux";
|
||||||
else if (navigator.appVersion.indexOf("X11") != -1) this.operating_system = "UNIX";
|
else if (navigator.appVersion.indexOf("X11") != -1) this.operating_system = "UNIX";
|
||||||
else this.operating_system = "Unknown";
|
else this.operating_system = "Unknown";
|
||||||
|
|
||||||
|
this.colorTable = [
|
||||||
|
"#8ecae6",
|
||||||
|
"#2a9d8f",
|
||||||
|
"#e9c46a",
|
||||||
|
"#f4a261",
|
||||||
|
"#e76f51",
|
||||||
|
"#ef476f",
|
||||||
|
"#ffc300"
|
||||||
|
];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// message = string
|
// message = string
|
||||||
|
@ -202,14 +215,61 @@ GUI_control.prototype.content_ready = function (callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
GUI_control.prototype.updateStatusBar = function() {
|
GUI_control.prototype.updateStatusBar = function() {
|
||||||
|
|
||||||
|
var armingFlags = {
|
||||||
|
'ARMED':(1 << 2),
|
||||||
|
//'WAS_EVER_ARMED':(1 << 3),
|
||||||
|
'SIMULATOR_MODE':(1 << 4),
|
||||||
|
'ARMING_DISABLED_FAILSAFE_SYSTEM':(1 << 7),
|
||||||
|
'ARMING_DISABLED_NOT_LEVEL':(1 << 8),
|
||||||
|
'ARMING_DISABLED_SENSORS_CALIBRATING':(1 << 9),
|
||||||
|
'ARMING_DISABLED_SYSTEM_OVERLOADED':(1 << 10),
|
||||||
|
'ARMING_DISABLED_NAVIGATION_UNSAFE':(1 << 11),
|
||||||
|
'ARMING_DISABLED_COMPASS_NOT_CALIBRATED':(1 << 12),
|
||||||
|
'ARMING_DISABLED_ACCELEROMETER_NOT_CALIBRATED':(1 << 13),
|
||||||
|
'ARMING_DISABLED_ARM_SWITCH':(1 << 14),
|
||||||
|
'ARMING_DISABLED_HARDWARE_FAILURE':(1 << 15),
|
||||||
|
'ARMING_DISABLED_BOXFAILSAFE':(1 << 16),
|
||||||
|
'ARMING_DISABLED_BOXKILLSWITCH':(1 << 17),
|
||||||
|
'ARMING_DISABLED_RC_LINK':(1 << 18),
|
||||||
|
'ARMING_DISABLED_THROTTLE':(1 << 19),
|
||||||
|
'ARMING_DISABLED_CLI':(1 << 20),
|
||||||
|
'ARMING_DISABLED_CMS_MENU':(1 << 21),
|
||||||
|
'ARMING_DISABLED_OSD_MENU':(1 << 22),
|
||||||
|
'ARMING_DISABLED_ROLLPITCH_NOT_CENTERED':(1 << 23),
|
||||||
|
'ARMING_DISABLED_SERVO_AUTOTRIM':(1 << 24),
|
||||||
|
'ARMING_DISABLED_OOM':(1 << 25),
|
||||||
|
'ARMING_DISABLED_INVALID_SETTING':(1 << 26),
|
||||||
|
'ARMING_DISABLED_PWM_OUTPUT_ERROR':(1 << 27),
|
||||||
|
'ARMING_DISABLED_NO_PREARM':(1 << 28),
|
||||||
|
'ARMING_DISABLED_DSHOT_BEEPER':(1 << 29),
|
||||||
|
'ARMING_DISABLED_LANDING_DETECTED':(1 << 30),
|
||||||
|
};
|
||||||
|
|
||||||
|
var activeArmFlags = [];
|
||||||
|
for(var i=0;i<32;i++) {
|
||||||
|
var checkBit = (1 << i);
|
||||||
|
if(Object.values(armingFlags).includes(checkBit) && (checkBit & CONFIG.armingFlags)) {
|
||||||
|
activeArmFlags.push(Object.keys(armingFlags)[Object.values(armingFlags).indexOf(checkBit)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$('span.i2c-error').text(CONFIG.i2cError);
|
$('span.i2c-error').text(CONFIG.i2cError);
|
||||||
$('span.cycle-time').text(CONFIG.cycleTime);
|
$('span.cycle-time').text(CONFIG.cycleTime);
|
||||||
$('span.cpu-load').text(chrome.i18n.getMessage('statusbar_cpu_load', [CONFIG.cpuload]));
|
$('span.cpu-load').text(chrome.i18n.getMessage('statusbar_cpu_load', [CONFIG.cpuload]));
|
||||||
|
$('span.arming-flags').text(activeArmFlags.length ? activeArmFlags.join(', ') : '-');
|
||||||
};
|
};
|
||||||
|
|
||||||
GUI_control.prototype.updateProfileChange = function() {
|
GUI_control.prototype.updateProfileChange = function(refresh) {
|
||||||
|
$('#mixerprofilechange').val(CONFIG.mixer_profile);
|
||||||
$('#profilechange').val(CONFIG.profile);
|
$('#profilechange').val(CONFIG.profile);
|
||||||
$('#batteryprofilechange').val(CONFIG.battery_profile);
|
$('#batteryprofilechange').val(CONFIG.battery_profile);
|
||||||
|
if (refresh) {
|
||||||
|
GUI.log(chrome.i18n.getMessage('loadedMixerProfile', [CONFIG.mixer_profile + 1]));
|
||||||
|
GUI.log(chrome.i18n.getMessage('pidTuning_LoadedProfile', [CONFIG.profile + 1]));
|
||||||
|
GUI.log(chrome.i18n.getMessage('loadedBatteryProfile', [CONFIG.battery_profile + 1]));
|
||||||
|
updateActivatedTab();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
GUI_control.prototype.fillSelect = function ($element, values, currentValue, unit) {
|
GUI_control.prototype.fillSelect = function ($element, values, currentValue, unit) {
|
||||||
|
@ -279,11 +339,27 @@ GUI_control.prototype.renderOperandValue = function ($container, operandMetadata
|
||||||
$t.append('<option value="' + i + '">' + i + '</option>');
|
$t.append('<option value="' + i + '">' + i + '</option>');
|
||||||
}
|
}
|
||||||
} else if (operandMetadata.type == "dictionary") {
|
} else if (operandMetadata.type == "dictionary") {
|
||||||
for (let k in operandMetadata.values) {
|
let operandValues = [];
|
||||||
if (operandMetadata.values.hasOwnProperty(k)) {
|
|
||||||
$t.append('<option value="' + k + '">' + operandMetadata.values[k] + '</option>');
|
for (let j in operandMetadata.values) {
|
||||||
|
if (operandMetadata.values.hasOwnProperty(j)) {
|
||||||
|
operandValues[parseInt(j,10)] = {
|
||||||
|
id: parseInt(j, 10),
|
||||||
|
name: operandMetadata.values[j],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operandValues.sort((a, b) => {
|
||||||
|
let ovAN = a.name.toLowerCase(),
|
||||||
|
ovBN = b.name.toLowerCase();
|
||||||
|
|
||||||
|
return (ovAN < ovBN) ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
operandValues.forEach( val => {
|
||||||
|
$t.append('<option value="' + val.id + '">' + val.name + '</option>');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$t.val(value);
|
$t.val(value);
|
||||||
|
@ -300,20 +376,117 @@ GUI_control.prototype.renderOperandValue = function ($container, operandMetadata
|
||||||
* @param {function} onChange
|
* @param {function} onChange
|
||||||
* @param {boolean} withAlways
|
* @param {boolean} withAlways
|
||||||
*/
|
*/
|
||||||
GUI_control.prototype.renderLogicConditionSelect = function ($container, logicConditions, current, onChange, withAlways) {
|
GUI_control.prototype.renderLogicConditionSelect = function ($container, logicConditions, current, onChange, withAlways, onlyEnabled) {
|
||||||
|
|
||||||
let $select = $container.append('<select class="mix-rule-condition">').find("select"),
|
let $select = $container.append('<select class="mix-rule-condition">').find("select"),
|
||||||
lcCount = logicConditions.getCount();
|
lcCount = logicConditions.getCount();
|
||||||
|
option = "";
|
||||||
|
|
||||||
if (withAlways) {
|
if (withAlways) {
|
||||||
$select.append('<option value="-1">Always</option>')
|
$select.append('<option value="-1">Always</option>')
|
||||||
}
|
}
|
||||||
for (let i = 0; i < lcCount ; i++) {
|
for (let i = 0; i < lcCount ; i++) {
|
||||||
$select.append('<option value="' + i + '">Logic Condition ' + i + ' </option>');
|
if (!onlyEnabled || i === current || (logicConditions.isEnabled(i))) {
|
||||||
|
option = '<option';
|
||||||
|
|
||||||
|
if (i === current && !logicConditions.isEnabled(i)) {
|
||||||
|
option+= ' class="lc_disabled"';
|
||||||
|
}
|
||||||
|
|
||||||
|
option+= ' value="' + i + '">Logic Condition ' + i + ' </option>';
|
||||||
|
|
||||||
|
$select.append(option);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$select.val(current).change(onChange);
|
$select.val(current).change(onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GUI_control.prototype.sliderize = function ($input, value, min, max) {
|
||||||
|
let scaledMax;
|
||||||
|
let scaledMin;
|
||||||
|
let scalingThreshold;
|
||||||
|
|
||||||
|
if ($input.data('normal-max')) {
|
||||||
|
scaledMax = max * 2;
|
||||||
|
scalingThreshold = Math.round(scaledMax * 0.8);
|
||||||
|
scaledMin = min *2;
|
||||||
|
} else {
|
||||||
|
scaledMax = max;
|
||||||
|
scaledMin = min;
|
||||||
|
scalingThreshold = scaledMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
let $range = $('<input type="range" min="' + scaledMin + '" max="' + scaledMax + '" value="' + value + '"/>');
|
||||||
|
if ($input.data('step')) {
|
||||||
|
$range.attr('step', $input.data('step'));
|
||||||
|
}
|
||||||
|
$range.css({
|
||||||
|
'display': 'block',
|
||||||
|
'flex-grow': 100,
|
||||||
|
'margin-left': '1em',
|
||||||
|
'margin-right': '1em',
|
||||||
|
});
|
||||||
|
|
||||||
|
$input.attr('min', min);
|
||||||
|
$input.attr('max', max);
|
||||||
|
$input.val(parseInt(value));
|
||||||
|
$input.css({
|
||||||
|
'width': 'auto',
|
||||||
|
'min-width': '75px',
|
||||||
|
});
|
||||||
|
|
||||||
|
$input.parent().css({
|
||||||
|
'display': 'flex',
|
||||||
|
'width': '100%'
|
||||||
|
});
|
||||||
|
$range.insertAfter($input);
|
||||||
|
|
||||||
|
$input.parent().find('.helpicon').css({
|
||||||
|
'top': '5px',
|
||||||
|
'left': '-10px'
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update slider to input
|
||||||
|
*/
|
||||||
|
$range.on('input', function() {
|
||||||
|
let val = $(this).val();
|
||||||
|
let normalMax = parseInt($input.data('normal-max'));
|
||||||
|
|
||||||
|
if (normalMax) {
|
||||||
|
if (val <= scalingThreshold) {
|
||||||
|
val = scaleRangeInt(val, scaledMin, scalingThreshold, min, normalMax);
|
||||||
|
} else {
|
||||||
|
val = scaleRangeInt(val, scalingThreshold + 1, scaledMax, normalMax + 1, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$input.val(val);
|
||||||
|
$input.trigger('updated');
|
||||||
|
});
|
||||||
|
|
||||||
|
$input.on('change', function() {
|
||||||
|
|
||||||
|
let val = $(this).val();
|
||||||
|
let newVal;
|
||||||
|
let normalMax = parseInt($input.data('normal-max'));
|
||||||
|
if (normalMax) {
|
||||||
|
if (val <= normalMax) {
|
||||||
|
newVal = scaleRangeInt(val, min, normalMax, scaledMin, scalingThreshold);
|
||||||
|
} else {
|
||||||
|
newVal = scaleRangeInt(val, normalMax + 1, max, scalingThreshold + 1, scaledMax);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
$range.val(newVal);
|
||||||
|
$input.trigger('updated');
|
||||||
|
});
|
||||||
|
|
||||||
|
$input.trigger('change');
|
||||||
|
};
|
||||||
|
|
||||||
// initialize object into GUI variable
|
// initialize object into GUI variable
|
||||||
var GUI = new GUI_control();
|
var GUI = new GUI_control();
|
||||||
|
|
|
@ -42,8 +42,9 @@ function generateFilename(prefix, suffix) {
|
||||||
|
|
||||||
if (CONFIG) {
|
if (CONFIG) {
|
||||||
if (CONFIG.flightControllerIdentifier) {
|
if (CONFIG.flightControllerIdentifier) {
|
||||||
filename = CONFIG.flightControllerIdentifier + '_' + filename;
|
filename = CONFIG.flightControllerIdentifier + '_' + CONFIG.flightControllerVersion + "_" + filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CONFIG.name && CONFIG.name.trim() !== '') {
|
if (CONFIG.name && CONFIG.name.trim() !== '') {
|
||||||
filename = filename + '_' + CONFIG.name.trim().replace(' ', '_');
|
filename = filename + '_' + CONFIG.name.trim().replace(' ', '_');
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,9 +218,10 @@ let LogicCondition = function (enabled, activatorId, operation, operandAType, op
|
||||||
if (self.getEnabled()) {
|
if (self.getEnabled()) {
|
||||||
GUI.renderLogicConditionSelect(
|
GUI.renderLogicConditionSelect(
|
||||||
$e,
|
$e,
|
||||||
LOGIC_CONDITIONS,
|
LOGIC_CONDITIONS,
|
||||||
self.getActivatorId,
|
self.getActivatorId,
|
||||||
self.onActivatorChange,
|
self.onActivatorChange,
|
||||||
|
true,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,6 +28,10 @@ let LogicConditionsCollection = function () {
|
||||||
return data.length
|
return data.length
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.isEnabled = function (lcID) {
|
||||||
|
return data[lcID].getEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
self.open = function () {
|
self.open = function () {
|
||||||
self.render();
|
self.render();
|
||||||
$container.show();
|
$container.show();
|
||||||
|
|
15
js/model.js
|
@ -32,6 +32,12 @@ const INPUT_STABILIZED_ROLL = 0,
|
||||||
INPUT_GIMBAL_PITCH = 12,
|
INPUT_GIMBAL_PITCH = 12,
|
||||||
INPUT_GIMBAL_ROLL = 13,
|
INPUT_GIMBAL_ROLL = 13,
|
||||||
INPUT_FEATURE_FLAPS = 14;
|
INPUT_FEATURE_FLAPS = 14;
|
||||||
|
STABILIZED_ROLL_POSITIVE = 23;
|
||||||
|
STABILIZED_ROLL_NEGATIVE = 24;
|
||||||
|
STABILIZED_PITCH_POSITIVE = 25;
|
||||||
|
STABILIZED_PITCH_NEGATIVE = 26;
|
||||||
|
STABILIZED_YAW_POSITIVE = 27;
|
||||||
|
STABILIZED_YAW_NEGATIVE = 28;
|
||||||
|
|
||||||
const
|
const
|
||||||
PLATFORM_MULTIROTOR = 0,
|
PLATFORM_MULTIROTOR = 0,
|
||||||
|
@ -344,6 +350,7 @@ const mixerList = [
|
||||||
enabled: true,
|
enabled: true,
|
||||||
legacy: true,
|
legacy: true,
|
||||||
platform: PLATFORM_AIRPLANE,
|
platform: PLATFORM_AIRPLANE,
|
||||||
|
motorStopOnLow: true,
|
||||||
motorMixer: [
|
motorMixer: [
|
||||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||||
],
|
],
|
||||||
|
@ -367,6 +374,7 @@ const mixerList = [
|
||||||
enabled: true,
|
enabled: true,
|
||||||
legacy: false,
|
legacy: false,
|
||||||
platform: PLATFORM_AIRPLANE,
|
platform: PLATFORM_AIRPLANE,
|
||||||
|
motorStopOnLow: true,
|
||||||
motorMixer: [
|
motorMixer: [
|
||||||
new MotorMixRule(1.0, 0.0, 0.0, 0.1),
|
new MotorMixRule(1.0, 0.0, 0.0, 0.1),
|
||||||
new MotorMixRule(1.0, 0.0, 0.0, -0.1)
|
new MotorMixRule(1.0, 0.0, 0.0, -0.1)
|
||||||
|
@ -393,6 +401,7 @@ const mixerList = [
|
||||||
enabled: true,
|
enabled: true,
|
||||||
legacy: true,
|
legacy: true,
|
||||||
platform: PLATFORM_AIRPLANE,
|
platform: PLATFORM_AIRPLANE,
|
||||||
|
motorStopOnLow: true,
|
||||||
hasFlaps: true,
|
hasFlaps: true,
|
||||||
motorMixer: [
|
motorMixer: [
|
||||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||||
|
@ -421,6 +430,7 @@ const mixerList = [
|
||||||
enabled: true,
|
enabled: true,
|
||||||
legacy: false,
|
legacy: false,
|
||||||
platform: PLATFORM_AIRPLANE,
|
platform: PLATFORM_AIRPLANE,
|
||||||
|
motorStopOnLow: true,
|
||||||
hasFlaps: true,
|
hasFlaps: true,
|
||||||
motorMixer: [
|
motorMixer: [
|
||||||
new MotorMixRule(1.0, 0.0, 0.0, 0.3),
|
new MotorMixRule(1.0, 0.0, 0.0, 0.3),
|
||||||
|
@ -450,6 +460,7 @@ const mixerList = [
|
||||||
enabled: true,
|
enabled: true,
|
||||||
legacy: false,
|
legacy: false,
|
||||||
platform: PLATFORM_AIRPLANE,
|
platform: PLATFORM_AIRPLANE,
|
||||||
|
motorStopOnLow: true,
|
||||||
hasFlaps: true,
|
hasFlaps: true,
|
||||||
motorMixer: [
|
motorMixer: [
|
||||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||||
|
@ -480,6 +491,7 @@ const mixerList = [
|
||||||
enabled: true,
|
enabled: true,
|
||||||
legacy: false,
|
legacy: false,
|
||||||
platform: PLATFORM_AIRPLANE,
|
platform: PLATFORM_AIRPLANE,
|
||||||
|
motorStopOnLow: true,
|
||||||
hasFlaps: true,
|
hasFlaps: true,
|
||||||
motorMixer: [
|
motorMixer: [
|
||||||
new MotorMixRule(1.0, 0.0, 0.0, 0.3),
|
new MotorMixRule(1.0, 0.0, 0.0, 0.3),
|
||||||
|
@ -510,6 +522,7 @@ const mixerList = [
|
||||||
enabled: true,
|
enabled: true,
|
||||||
legacy: false,
|
legacy: false,
|
||||||
platform: PLATFORM_AIRPLANE,
|
platform: PLATFORM_AIRPLANE,
|
||||||
|
motorStopOnLow: true,
|
||||||
motorMixer: [
|
motorMixer: [
|
||||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||||
],
|
],
|
||||||
|
@ -536,6 +549,7 @@ const mixerList = [
|
||||||
legacy: false,
|
legacy: false,
|
||||||
platform: PLATFORM_AIRPLANE,
|
platform: PLATFORM_AIRPLANE,
|
||||||
hasFlaps: true,
|
hasFlaps: true,
|
||||||
|
motorStopOnLow: true,
|
||||||
motorMixer: [
|
motorMixer: [
|
||||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||||
],
|
],
|
||||||
|
@ -562,6 +576,7 @@ const mixerList = [
|
||||||
enabled: false,
|
enabled: false,
|
||||||
legacy: true,
|
legacy: true,
|
||||||
platform: PLATFORM_AIRPLANE,
|
platform: PLATFORM_AIRPLANE,
|
||||||
|
motorStopOnLow: true,
|
||||||
motorMixer: [],
|
motorMixer: [],
|
||||||
servoMixer: []
|
servoMixer: []
|
||||||
}, // 24
|
}, // 24
|
||||||
|
|
|
@ -6,7 +6,7 @@ var MotorMixRule = function (throttle, roll, pitch, yaw) {
|
||||||
var self = {};
|
var self = {};
|
||||||
|
|
||||||
self.fromMsp = function (mspThrottle, mspRoll, mspPitch, mspYaw) {
|
self.fromMsp = function (mspThrottle, mspRoll, mspPitch, mspYaw) {
|
||||||
throttle = mspThrottle / 1000;
|
throttle = Math.round(((mspThrottle / 1000) - 2) * 1000) / 1000;
|
||||||
roll = Math.round(((mspRoll / 1000) - 2) * 1000) / 1000;
|
roll = Math.round(((mspRoll / 1000) - 2) * 1000) / 1000;
|
||||||
pitch = Math.round(((mspPitch / 1000) - 2) * 1000) / 1000;
|
pitch = Math.round(((mspPitch / 1000) - 2) * 1000) / 1000;
|
||||||
yaw = Math.round(((mspYaw / 1000) - 2) * 1000) / 1000;
|
yaw = Math.round(((mspYaw / 1000) - 2) * 1000) / 1000;
|
||||||
|
@ -17,11 +17,11 @@ var MotorMixRule = function (throttle, roll, pitch, yaw) {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getThrottle = function () {
|
self.getThrottle = function () {
|
||||||
return constrain(parseFloat(throttle, 10), 0, 1);
|
return constrain(parseFloat(throttle, 10), -2, 2);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getThrottleForMsp = function () {
|
self.getThrottleForMsp = function () {
|
||||||
return self.getThrottle() * 1000;
|
return (self.getThrottle()+2) * 1000;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.setThrottle = function (data) {
|
self.setThrottle = function (data) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ var MotorMixerRuleCollection = function () {
|
||||||
|
|
||||||
let self = {},
|
let self = {},
|
||||||
data = [],
|
data = [],
|
||||||
|
inactiveData = [],
|
||||||
maxMotorCount = 8;
|
maxMotorCount = 8;
|
||||||
|
|
||||||
self.setMotorCount = function (value) {
|
self.setMotorCount = function (value) {
|
||||||
|
@ -16,7 +17,11 @@ var MotorMixerRuleCollection = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.put = function (element) {
|
self.put = function (element) {
|
||||||
data.push(element);
|
if (data.length < self.getMotorCount()){
|
||||||
|
data.push(element);
|
||||||
|
}else{
|
||||||
|
inactiveData.push(element); //store the data for mixer_profile 2
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.get = function () {
|
self.get = function () {
|
||||||
|
@ -30,18 +35,25 @@ var MotorMixerRuleCollection = function () {
|
||||||
|
|
||||||
self.flush = function () {
|
self.flush = function () {
|
||||||
data = [];
|
data = [];
|
||||||
|
inactiveData = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
self.cleanup = function () {
|
self.cleanup = function () {
|
||||||
var tmpData = [];
|
var tmpData = [];
|
||||||
|
var tmpInactiveData = [];
|
||||||
|
|
||||||
data.forEach(function (element) {
|
data.forEach(function (element) {
|
||||||
if (element.isUsed()) {
|
if (element.isUsed()) {
|
||||||
tmpData.push(element);
|
tmpData.push(element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
inactiveData.forEach(function (element) {
|
||||||
|
if (element.isUsed()) {
|
||||||
|
tmpInactiveData.push(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
data = tmpData;
|
data = tmpData;
|
||||||
|
inactiveData = tmpInactiveData;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.inflate = function () {
|
self.inflate = function () {
|
||||||
|
@ -55,7 +67,7 @@ var MotorMixerRuleCollection = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getNumberOfConfiguredMotors = function () {
|
self.getNumberOfConfiguredMotors = function () {
|
||||||
return data.length;
|
return data.length > inactiveData.length ? data.length : inactiveData.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -73,7 +73,7 @@ var MSP = {
|
||||||
ledDirectionLetters: ['n', 'e', 's', 'w', 'u', 'd'], // in LSB bit order
|
ledDirectionLetters: ['n', 'e', 's', 'w', 'u', 'd'], // in LSB bit order
|
||||||
ledFunctionLetters: ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b', 'l'], // in LSB bit order
|
ledFunctionLetters: ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b', 'l'], // in LSB bit order
|
||||||
ledBaseFunctionLetters: ['c', 'f', 'a', 'l', 's', 'g', 'r', 'h'], // in LSB bit
|
ledBaseFunctionLetters: ['c', 'f', 'a', 'l', 's', 'g', 'r', 'h'], // in LSB bit
|
||||||
ledOverlayLetters: ['t', 'o', 'b', 'n', 'i', 'w'], // in LSB bit
|
ledOverlayLetters: ['t', 'o', 'b', 'n', 'i', 'w', 'e'], // in LSB bit
|
||||||
|
|
||||||
last_received_timestamp: null,
|
last_received_timestamp: null,
|
||||||
analog_last_received_timestamp: null,
|
analog_last_received_timestamp: null,
|
||||||
|
|
|
@ -180,6 +180,11 @@ var MSPCodes = {
|
||||||
MSPV2_INAV_SET_RATE_PROFILE: 0x2008,
|
MSPV2_INAV_SET_RATE_PROFILE: 0x2008,
|
||||||
MSPV2_INAV_AIR_SPEED: 0x2009,
|
MSPV2_INAV_AIR_SPEED: 0x2009,
|
||||||
MSPV2_INAV_OUTPUT_MAPPING: 0x200A,
|
MSPV2_INAV_OUTPUT_MAPPING: 0x200A,
|
||||||
|
MSP2_INAV_MC_BRAKING: 0x200B,
|
||||||
|
MSP2_INAV_SET_MC_BRAKING: 0x200C,
|
||||||
|
MSPV2_INAV_OUTPUT_MAPPING_EXT: 0x200D,
|
||||||
|
MSP2_INAV_TIMER_OUTPUT_MODE: 0x200E,
|
||||||
|
MSP2_INAV_SET_TIMER_OUTPUT_MODE: 0x200F,
|
||||||
|
|
||||||
MSP2_INAV_MIXER: 0x2010,
|
MSP2_INAV_MIXER: 0x2010,
|
||||||
MSP2_INAV_SET_MIXER: 0x2011,
|
MSP2_INAV_SET_MIXER: 0x2011,
|
||||||
|
@ -191,9 +196,6 @@ var MSPCodes = {
|
||||||
MSP2_INAV_OSD_PREFERENCES: 0x2016,
|
MSP2_INAV_OSD_PREFERENCES: 0x2016,
|
||||||
MSP2_INAV_OSD_SET_PREFERENCES: 0x2017,
|
MSP2_INAV_OSD_SET_PREFERENCES: 0x2017,
|
||||||
|
|
||||||
MSP2_INAV_MC_BRAKING: 0x200B,
|
|
||||||
MSP2_INAV_SET_MC_BRAKING: 0x200C,
|
|
||||||
|
|
||||||
MSP2_INAV_SELECT_BATTERY_PROFILE: 0x2018,
|
MSP2_INAV_SELECT_BATTERY_PROFILE: 0x2018,
|
||||||
|
|
||||||
MSP2_INAV_DEBUG: 0x2019,
|
MSP2_INAV_DEBUG: 0x2019,
|
||||||
|
@ -217,6 +219,7 @@ var MSPCodes = {
|
||||||
MSP2_INAV_SET_PROGRAMMING_PID: 0x2029,
|
MSP2_INAV_SET_PROGRAMMING_PID: 0x2029,
|
||||||
MSP2_INAV_PROGRAMMING_PID_STATUS: 0x202A,
|
MSP2_INAV_PROGRAMMING_PID_STATUS: 0x202A,
|
||||||
|
|
||||||
|
|
||||||
MSP2_PID: 0x2030,
|
MSP2_PID: 0x2030,
|
||||||
MSP2_SET_PID: 0x2031,
|
MSP2_SET_PID: 0x2031,
|
||||||
|
|
||||||
|
@ -231,5 +234,18 @@ var MSPCodes = {
|
||||||
MSP2_INAV_SAFEHOME: 0x2038,
|
MSP2_INAV_SAFEHOME: 0x2038,
|
||||||
MSP2_INAV_SET_SAFEHOME: 0x2039,
|
MSP2_INAV_SET_SAFEHOME: 0x2039,
|
||||||
|
|
||||||
MSP2_INAV_LOGIC_CONDITIONS_SINGLE: 0x203B
|
MSP2_INAV_LOGIC_CONDITIONS_SINGLE: 0x203B,
|
||||||
|
|
||||||
|
MSP2_INAV_LED_STRIP_CONFIG_EX: 0x2048,
|
||||||
|
MSP2_INAV_SET_LED_STRIP_CONFIG_EX: 0x2049,
|
||||||
|
|
||||||
|
MSP2_INAV_RATE_DYNAMICS: 0x2060,
|
||||||
|
MSP2_INAV_SET_RATE_DYNAMICS: 0x2061,
|
||||||
|
|
||||||
|
MSP2_INAV_EZ_TUNE: 0x2070,
|
||||||
|
MSP2_INAV_EZ_TUNE_SET: 0x2071,
|
||||||
|
|
||||||
|
MSP2_INAV_SELECT_MIXER_PROFILE: 0x2080,
|
||||||
|
|
||||||
|
MSP2_ADSB_VEHICLE_LIST: 0x2090,
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,9 +42,9 @@ var mspHelper = (function (gui) {
|
||||||
'GSM_SMS': 19,
|
'GSM_SMS': 19,
|
||||||
'FRSKY_OSD': 20,
|
'FRSKY_OSD': 20,
|
||||||
'DJI_FPV': 21,
|
'DJI_FPV': 21,
|
||||||
|
'SBUS_OUTPUT': 22,
|
||||||
'SMARTPORT_MASTER': 23,
|
'SMARTPORT_MASTER': 23,
|
||||||
'IMU2': 24,
|
'MSP_DISPLAYPORT': 25,
|
||||||
'HDZERO_VTX': 25,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Required for MSP_DEBUGMSG because console.log() doesn't allow omitting
|
// Required for MSP_DEBUGMSG because console.log() doesn't allow omitting
|
||||||
|
@ -69,6 +69,7 @@ var mspHelper = (function (gui) {
|
||||||
color;
|
color;
|
||||||
if (!dataHandler.unsupported || dataHandler.unsupported) switch (dataHandler.code) {
|
if (!dataHandler.unsupported || dataHandler.unsupported) switch (dataHandler.code) {
|
||||||
case MSPCodes.MSPV2_INAV_STATUS:
|
case MSPCodes.MSPV2_INAV_STATUS:
|
||||||
|
let profile_changed = false;
|
||||||
CONFIG.cycleTime = data.getUint16(offset, true);
|
CONFIG.cycleTime = data.getUint16(offset, true);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
CONFIG.i2cError = data.getUint16(offset, true);
|
CONFIG.i2cError = data.getUint16(offset, true);
|
||||||
|
@ -77,13 +78,28 @@ var mspHelper = (function (gui) {
|
||||||
offset += 2;
|
offset += 2;
|
||||||
CONFIG.cpuload = data.getUint16(offset, true);
|
CONFIG.cpuload = data.getUint16(offset, true);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
profile_byte = data.getUint8(offset++)
|
profile_byte = data.getUint8(offset++)
|
||||||
CONFIG.profile = profile_byte & 0x0F;
|
let profile = profile_byte & 0x0F;
|
||||||
CONFIG.battery_profile = (profile_byte & 0xF0) >> 4;
|
profile_changed |= (profile !== CONFIG.profile) && (CONFIG.profile !==-1);
|
||||||
|
CONFIG.profile = profile;
|
||||||
|
|
||||||
|
let battery_profile = (profile_byte & 0xF0) >> 4;
|
||||||
|
profile_changed |= (battery_profile !== CONFIG.battery_profile) && (CONFIG.battery_profile !==-1);
|
||||||
|
CONFIG.battery_profile = battery_profile;
|
||||||
|
|
||||||
CONFIG.armingFlags = data.getUint32(offset, true);
|
CONFIG.armingFlags = data.getUint32(offset, true);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
|
//As there are 8 bytes for mspBoxModeFlags (number of bytes is actually variable)
|
||||||
|
//read mixer profile as the last byte in the the message
|
||||||
|
profile_byte = data.getUint8(dataHandler.message_length_expected - 1);
|
||||||
|
let mixer_profile = profile_byte & 0x0F;
|
||||||
|
profile_changed |= (mixer_profile !== CONFIG.mixer_profile) && (CONFIG.mixer_profile !==-1);
|
||||||
|
CONFIG.mixer_profile = mixer_profile;
|
||||||
|
|
||||||
gui.updateStatusBar();
|
gui.updateStatusBar();
|
||||||
gui.updateProfileChange();
|
gui.updateProfileChange(profile_changed);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSPCodes.MSP_ACTIVEBOXES:
|
case MSPCodes.MSP_ACTIVEBOXES:
|
||||||
|
@ -104,7 +120,6 @@ var mspHelper = (function (gui) {
|
||||||
SENSOR_STATUS.rangeHwStatus = data.getUint8(6);
|
SENSOR_STATUS.rangeHwStatus = data.getUint8(6);
|
||||||
SENSOR_STATUS.speedHwStatus = data.getUint8(7);
|
SENSOR_STATUS.speedHwStatus = data.getUint8(7);
|
||||||
SENSOR_STATUS.flowHwStatus = data.getUint8(8);
|
SENSOR_STATUS.flowHwStatus = data.getUint8(8);
|
||||||
SENSOR_STATUS.imu2HwStatus = data.getUint8(9);
|
|
||||||
sensor_status_ex(SENSOR_STATUS);
|
sensor_status_ex(SENSOR_STATUS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -172,6 +187,35 @@ var mspHelper = (function (gui) {
|
||||||
GPS_DATA.eph = data.getUint16(16, true);
|
GPS_DATA.eph = data.getUint16(16, true);
|
||||||
GPS_DATA.epv = data.getUint16(18, true);
|
GPS_DATA.epv = data.getUint16(18, true);
|
||||||
break;
|
break;
|
||||||
|
case MSPCodes.MSP2_ADSB_VEHICLE_LIST:
|
||||||
|
var byteOffsetCounter = 0;
|
||||||
|
ADSB_VEHICLES.vehicles = [];
|
||||||
|
ADSB_VEHICLES.vehiclesCount = data.getUint8(byteOffsetCounter++);
|
||||||
|
ADSB_VEHICLES.callsignLength = data.getUint8(byteOffsetCounter++);
|
||||||
|
|
||||||
|
for(i = 0; i < ADSB_VEHICLES.vehiclesCount; i++){
|
||||||
|
|
||||||
|
var vehicle = {callSignByteArray: [], callsign: "", icao: 0, lat: 0, lon: 0, alt: 0, heading: 0, ttl: 0, tslc: 0, emitterType: 0};
|
||||||
|
|
||||||
|
for(ii = 0; ii < ADSB_VEHICLES.callsignLength; ii++){
|
||||||
|
vehicle.callSignByteArray.push(data.getUint8(byteOffsetCounter++));
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle.callsign = (String.fromCharCode(...vehicle.callSignByteArray)).replace(/[^\x20-\x7E]/g, '');
|
||||||
|
vehicle.icao = data.getUint32(byteOffsetCounter, true); byteOffsetCounter += 4;
|
||||||
|
vehicle.lat = data.getInt32(byteOffsetCounter, true); byteOffsetCounter += 4;
|
||||||
|
vehicle.lon = data.getInt32(byteOffsetCounter, true); byteOffsetCounter += 4;
|
||||||
|
vehicle.altCM = data.getInt32(byteOffsetCounter, true); byteOffsetCounter += 4;
|
||||||
|
vehicle.headingDegrees = data.getUint16(byteOffsetCounter, true); byteOffsetCounter += 2;
|
||||||
|
vehicle.tslc = data.getUint8(byteOffsetCounter++);
|
||||||
|
vehicle.emitterType = data.getUint8(byteOffsetCounter++);
|
||||||
|
vehicle.ttl = data.getUint8(byteOffsetCounter++);
|
||||||
|
|
||||||
|
ADSB_VEHICLES.vehicles.push(vehicle);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case MSPCodes.MSP_ATTITUDE:
|
case MSPCodes.MSP_ATTITUDE:
|
||||||
SENSOR_DATA.kinematics[0] = data.getInt16(0, true) / 10.0; // x
|
SENSOR_DATA.kinematics[0] = data.getInt16(0, true) / 10.0; // x
|
||||||
SENSOR_DATA.kinematics[1] = data.getInt16(2, true) / 10.0; // y
|
SENSOR_DATA.kinematics[1] = data.getInt16(2, true) / 10.0; // y
|
||||||
|
@ -477,9 +521,9 @@ var mspHelper = (function (gui) {
|
||||||
data.getInt8(i + 13)
|
data.getInt8(i + 13)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSPCodes.MSP2_INAV_LOGIC_CONDITIONS_SINGLE:
|
case MSPCodes.MSP2_INAV_LOGIC_CONDITIONS_SINGLE:
|
||||||
LOGIC_CONDITIONS.put(new LogicCondition(
|
LOGIC_CONDITIONS.put(new LogicCondition(
|
||||||
data.getInt8(0),
|
data.getInt8(0),
|
||||||
|
@ -777,6 +821,18 @@ var mspHelper = (function (gui) {
|
||||||
CONFIG.boardIdentifier = identifier;
|
CONFIG.boardIdentifier = identifier;
|
||||||
CONFIG.boardVersion = data.getUint16(offset, 1);
|
CONFIG.boardVersion = data.getUint16(offset, 1);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
if (semver.gt(CONFIG.flightControllerVersion, "4.1.0")) {
|
||||||
|
CONFIG.osdUsed = data.getUint8(offset++);
|
||||||
|
CONFIG.commCompatability = data.getUint8(offset++);
|
||||||
|
let targetNameLen = data.getUint8(offset++);
|
||||||
|
let targetName = "";
|
||||||
|
targetNameLen += offset;
|
||||||
|
for (offset = offset; offset < targetNameLen; offset++) {
|
||||||
|
targetName += String.fromCharCode(data.getUint8(offset));
|
||||||
|
}
|
||||||
|
CONFIG.target = targetName;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSPCodes.MSP_SET_CHANNEL_FORWARDING:
|
case MSPCodes.MSP_SET_CHANNEL_FORWARDING:
|
||||||
|
@ -797,7 +853,7 @@ var mspHelper = (function (gui) {
|
||||||
msp_baudrate: BAUD_RATES[data.getUint8(offset + 5)],
|
msp_baudrate: BAUD_RATES[data.getUint8(offset + 5)],
|
||||||
sensors_baudrate: BAUD_RATES[data.getUint8(offset + 6)],
|
sensors_baudrate: BAUD_RATES[data.getUint8(offset + 6)],
|
||||||
telemetry_baudrate: BAUD_RATES[data.getUint8(offset + 7)],
|
telemetry_baudrate: BAUD_RATES[data.getUint8(offset + 7)],
|
||||||
blackbox_baudrate: BAUD_RATES[data.getUint8(offset + 8)]
|
peripherals_baudrate: BAUD_RATES[data.getUint8(offset + 8)]
|
||||||
};
|
};
|
||||||
|
|
||||||
offset += bytesPerPort;
|
offset += bytesPerPort;
|
||||||
|
@ -1018,9 +1074,66 @@ var mspHelper = (function (gui) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MSPCodes.MSP2_INAV_LED_STRIP_CONFIG_EX:
|
||||||
|
//noinspection JSUndeclaredVariable
|
||||||
|
LED_STRIP = [];
|
||||||
|
|
||||||
|
var ledCount = data.byteLength / 5;
|
||||||
|
var directionMask,
|
||||||
|
directions,
|
||||||
|
directionLetterIndex,
|
||||||
|
functions,
|
||||||
|
led;
|
||||||
|
|
||||||
|
for (i = 0; offset < data.byteLength && i < ledCount; i++) {
|
||||||
|
var mask = data.getUint32(offset, 1);
|
||||||
|
offset += 4;
|
||||||
|
var extra = data.getUint8(offset, 1);
|
||||||
|
offset++;
|
||||||
|
|
||||||
|
var functionId = (mask >> 8) & 0xFF;
|
||||||
|
|
||||||
|
functions = [];
|
||||||
|
for (var baseFunctionLetterIndex = 0; baseFunctionLetterIndex < MSP.ledBaseFunctionLetters.length; baseFunctionLetterIndex++) {
|
||||||
|
if (functionId == baseFunctionLetterIndex) {
|
||||||
|
functions.push(MSP.ledBaseFunctionLetters[baseFunctionLetterIndex]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var overlayMask = (mask >> 16) & 0xFF;
|
||||||
|
for (var overlayLetterIndex = 0; overlayLetterIndex < MSP.ledOverlayLetters.length; overlayLetterIndex++) {
|
||||||
|
if (bit_check(overlayMask, overlayLetterIndex)) {
|
||||||
|
functions.push(MSP.ledOverlayLetters[overlayLetterIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
directionMask = (mask >> 28) & 0xF | ((extra & 0x3) << 4);
|
||||||
|
|
||||||
|
directions = [];
|
||||||
|
for (directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
|
||||||
|
if (bit_check(directionMask, directionLetterIndex)) {
|
||||||
|
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
led = {
|
||||||
|
y: (mask) & 0xF,
|
||||||
|
x: (mask >> 4) & 0xF,
|
||||||
|
functions: functions,
|
||||||
|
color: (mask >> 24) & 0xF,
|
||||||
|
directions: directions,
|
||||||
|
parameters: (extra >> 2) & 0x3F
|
||||||
|
};
|
||||||
|
|
||||||
|
LED_STRIP.push(led);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MSPCodes.MSP_SET_LED_STRIP_CONFIG:
|
case MSPCodes.MSP_SET_LED_STRIP_CONFIG:
|
||||||
console.log('Led strip config saved');
|
console.log('Led strip config saved');
|
||||||
break;
|
break;
|
||||||
|
case MSPCodes.MSP2_INAV_SET_LED_STRIP_CONFIG_EX:
|
||||||
|
console.log('Led strip extended config saved');
|
||||||
|
break;
|
||||||
case MSPCodes.MSP_LED_COLORS:
|
case MSPCodes.MSP_LED_COLORS:
|
||||||
|
|
||||||
//noinspection JSUndeclaredVariable
|
//noinspection JSUndeclaredVariable
|
||||||
|
@ -1386,7 +1499,8 @@ var mspHelper = (function (gui) {
|
||||||
break;
|
break;
|
||||||
case MSPCodes.MSP2_INAV_MIXER:
|
case MSPCodes.MSP2_INAV_MIXER:
|
||||||
MIXER_CONFIG.yawMotorDirection = data.getInt8(0);
|
MIXER_CONFIG.yawMotorDirection = data.getInt8(0);
|
||||||
MIXER_CONFIG.yawJumpPreventionLimit = data.getUint16(1, true);
|
MIXER_CONFIG.yawJumpPreventionLimit = data.getUint8(1, true);
|
||||||
|
MIXER_CONFIG.motorStopOnLow = data.getUint8(2, true);
|
||||||
MIXER_CONFIG.platformType = data.getInt8(3);
|
MIXER_CONFIG.platformType = data.getInt8(3);
|
||||||
MIXER_CONFIG.hasFlaps = data.getInt8(4);
|
MIXER_CONFIG.hasFlaps = data.getInt8(4);
|
||||||
MIXER_CONFIG.appliedMixerPreset = data.getInt16(5, true);
|
MIXER_CONFIG.appliedMixerPreset = data.getInt16(5, true);
|
||||||
|
@ -1412,10 +1526,38 @@ var mspHelper = (function (gui) {
|
||||||
case MSPCodes.MSP2_INAV_OSD_SET_PREFERENCES:
|
case MSPCodes.MSP2_INAV_OSD_SET_PREFERENCES:
|
||||||
console.log('OSD preferences saved');
|
console.log('OSD preferences saved');
|
||||||
break;
|
break;
|
||||||
|
case MSPCodes.MSP2_INAV_SELECT_BATTERY_PROFILE:
|
||||||
|
console.log('Battery profile selected');
|
||||||
|
break;
|
||||||
case MSPCodes.MSPV2_INAV_OUTPUT_MAPPING:
|
case MSPCodes.MSPV2_INAV_OUTPUT_MAPPING:
|
||||||
OUTPUT_MAPPING.flush();
|
OUTPUT_MAPPING.flush();
|
||||||
for (i = 0; i < data.byteLength; ++i)
|
for (i = 0; i < data.byteLength; ++i)
|
||||||
OUTPUT_MAPPING.put(data.getUint8(i));
|
OUTPUT_MAPPING.put({
|
||||||
|
'timerId': i,
|
||||||
|
'usageFlags': data.getUint8(i)});
|
||||||
|
break;
|
||||||
|
case MSPCodes.MSPV2_INAV_OUTPUT_MAPPING_EXT:
|
||||||
|
OUTPUT_MAPPING.flush();
|
||||||
|
for (i = 0; i < data.byteLength; i += 2) {
|
||||||
|
timerId = data.getUint8(i);
|
||||||
|
usageFlags = data.getUint8(i + 1);
|
||||||
|
OUTPUT_MAPPING.put(
|
||||||
|
{
|
||||||
|
'timerId': timerId,
|
||||||
|
'usageFlags': usageFlags
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSPCodes.MSP2_INAV_TIMER_OUTPUT_MODE:
|
||||||
|
if(data.byteLength > 2) {
|
||||||
|
OUTPUT_MAPPING.flushTimerOverrides();
|
||||||
|
}
|
||||||
|
for (i = 0; i < data.byteLength; i += 2) {
|
||||||
|
timerId = data.getUint8(i);
|
||||||
|
outputMode = data.getUint8(i + 1);
|
||||||
|
OUTPUT_MAPPING.setTimerOverride(timerId, outputMode);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSPCodes.MSP2_INAV_MC_BRAKING:
|
case MSPCodes.MSP2_INAV_MC_BRAKING:
|
||||||
|
@ -1465,6 +1607,35 @@ var mspHelper = (function (gui) {
|
||||||
console.log('Safehome points saved');
|
console.log('Safehome points saved');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSPCodes.MSP2_INAV_RATE_DYNAMICS:
|
||||||
|
RATE_DYNAMICS.sensitivityCenter = data.getUint8(0);
|
||||||
|
RATE_DYNAMICS.sensitivityEnd = data.getUint8(1);
|
||||||
|
RATE_DYNAMICS.correctionCenter = data.getUint8(2);
|
||||||
|
RATE_DYNAMICS.correctionEnd = data.getUint8(3);
|
||||||
|
RATE_DYNAMICS.weightCenter = data.getUint8(4);
|
||||||
|
RATE_DYNAMICS.weightEnd = data.getUint8(5);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSPCodes.MSP2_INAV_SET_RATE_DYNAMICS:
|
||||||
|
console.log('Rate dynamics saved');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSPCodes.MSP2_INAV_EZ_TUNE:
|
||||||
|
EZ_TUNE.enabled = data.getUint8(0);
|
||||||
|
EZ_TUNE.filterHz = data.getUint16(1, true);
|
||||||
|
EZ_TUNE.axisRatio = data.getUint8(3);
|
||||||
|
EZ_TUNE.response = data.getUint8(4);
|
||||||
|
EZ_TUNE.damping = data.getUint8(5);
|
||||||
|
EZ_TUNE.stability = data.getUint8(6);
|
||||||
|
EZ_TUNE.aggressiveness = data.getUint8(7);
|
||||||
|
EZ_TUNE.rate = data.getUint8(8);
|
||||||
|
EZ_TUNE.expo = data.getUint8(9);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSPCodes.MSP2_INAV_EZ_TUNE_SET:
|
||||||
|
console.log('EzTune settings saved');
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.log('Unknown code detected: ' + dataHandler.code);
|
console.log('Unknown code detected: ' + dataHandler.code);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1772,7 +1943,7 @@ var mspHelper = (function (gui) {
|
||||||
buffer.push(BAUD_RATES.indexOf(serialPort.msp_baudrate));
|
buffer.push(BAUD_RATES.indexOf(serialPort.msp_baudrate));
|
||||||
buffer.push(BAUD_RATES.indexOf(serialPort.sensors_baudrate));
|
buffer.push(BAUD_RATES.indexOf(serialPort.sensors_baudrate));
|
||||||
buffer.push(BAUD_RATES.indexOf(serialPort.telemetry_baudrate));
|
buffer.push(BAUD_RATES.indexOf(serialPort.telemetry_baudrate));
|
||||||
buffer.push(BAUD_RATES.indexOf(serialPort.blackbox_baudrate));
|
buffer.push(BAUD_RATES.indexOf(serialPort.peripherals_baudrate));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2062,8 +2233,8 @@ var mspHelper = (function (gui) {
|
||||||
|
|
||||||
case MSPCodes.MSP2_INAV_SET_MIXER:
|
case MSPCodes.MSP2_INAV_SET_MIXER:
|
||||||
buffer.push(MIXER_CONFIG.yawMotorDirection);
|
buffer.push(MIXER_CONFIG.yawMotorDirection);
|
||||||
buffer.push(lowByte(MIXER_CONFIG.yawJumpPreventionLimit));
|
buffer.push(MIXER_CONFIG.yawJumpPreventionLimit);
|
||||||
buffer.push(highByte(MIXER_CONFIG.yawJumpPreventionLimit));
|
buffer.push(MIXER_CONFIG.motorStopOnLow);
|
||||||
buffer.push(MIXER_CONFIG.platformType);
|
buffer.push(MIXER_CONFIG.platformType);
|
||||||
buffer.push(MIXER_CONFIG.hasFlaps);
|
buffer.push(MIXER_CONFIG.hasFlaps);
|
||||||
buffer.push(lowByte(MIXER_CONFIG.appliedMixerPreset));
|
buffer.push(lowByte(MIXER_CONFIG.appliedMixerPreset));
|
||||||
|
@ -2092,6 +2263,31 @@ var mspHelper = (function (gui) {
|
||||||
buffer.push(BRAKING_CONFIG.bankAngle);
|
buffer.push(BRAKING_CONFIG.bankAngle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSPCodes.MSP2_INAV_SET_RATE_DYNAMICS:
|
||||||
|
buffer.push(RATE_DYNAMICS.sensitivityCenter);
|
||||||
|
buffer.push(RATE_DYNAMICS.sensitivityEnd);
|
||||||
|
buffer.push(RATE_DYNAMICS.correctionCenter);
|
||||||
|
buffer.push(RATE_DYNAMICS.correctionEnd);
|
||||||
|
buffer.push(RATE_DYNAMICS.weightCenter);
|
||||||
|
buffer.push(RATE_DYNAMICS.weightEnd);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSPCodes.MSP2_INAV_EZ_TUNE_SET:
|
||||||
|
|
||||||
|
buffer.push(EZ_TUNE.enabled);
|
||||||
|
buffer.push(lowByte(EZ_TUNE.filterHz));
|
||||||
|
buffer.push(highByte(EZ_TUNE.filterHz));
|
||||||
|
buffer.push(EZ_TUNE.axisRatio);
|
||||||
|
buffer.push(EZ_TUNE.response);
|
||||||
|
buffer.push(EZ_TUNE.damping);
|
||||||
|
buffer.push(EZ_TUNE.stability);
|
||||||
|
buffer.push(EZ_TUNE.aggressiveness);
|
||||||
|
buffer.push(EZ_TUNE.rate);
|
||||||
|
buffer.push(EZ_TUNE.expo);
|
||||||
|
console.log(buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2270,8 +2466,8 @@ var mspHelper = (function (gui) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.loadLogicConditions = function (callback) {
|
self.loadLogicConditions = function (callback) {
|
||||||
if (semver.gte(CONFIG.flightControllerVersion, "5.0.0")) {
|
if (semver.gte(CONFIG.flightControllerVersion, "5.0.0")) {
|
||||||
LOGIC_CONDITIONS.flush();
|
LOGIC_CONDITIONS.flush();
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
MSP.send_message(MSPCodes.MSP2_INAV_LOGIC_CONDITIONS_SINGLE, [idx], false, nextLogicCondition);
|
MSP.send_message(MSPCodes.MSP2_INAV_LOGIC_CONDITIONS_SINGLE, [idx], false, nextLogicCondition);
|
||||||
|
@ -2599,11 +2795,12 @@ var mspHelper = (function (gui) {
|
||||||
buffer.push(ledIndex);
|
buffer.push(ledIndex);
|
||||||
|
|
||||||
var mask = 0;
|
var mask = 0;
|
||||||
|
var extra = 0;
|
||||||
/*
|
/*
|
||||||
ledDirectionLetters: ['n', 'e', 's', 'w', 'u', 'd'], // in LSB bit order
|
ledDirectionLetters: ['n', 'e', 's', 'w', 'u', 'd'], // in LSB bit order
|
||||||
ledFunctionLetters: ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b', 'l'], // in LSB bit order
|
ledFunctionLetters: ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b', 'l'], // in LSB bit order
|
||||||
ledBaseFunctionLetters: ['c', 'f', 'a', 'l', 's', 'g', 'r', 'h'], // in LSB bit
|
ledBaseFunctionLetters: ['c', 'f', 'a', 'l', 's', 'g', 'r', 'h'], // in LSB bit
|
||||||
ledOverlayLetters: ['t', 'o', 'b', 'n', 'i', 'w'], // in LSB bit
|
ledOverlayLetters: ['t', 'o', 'b', 'n', 'i', 'w', 'e'], // in LSB bit
|
||||||
|
|
||||||
*/
|
*/
|
||||||
mask |= (led.y << 0);
|
mask |= (led.y << 0);
|
||||||
|
@ -2621,29 +2818,32 @@ var mspHelper = (function (gui) {
|
||||||
|
|
||||||
bitIndex = MSP.ledOverlayLetters.indexOf(led.functions[overlayLetterIndex]);
|
bitIndex = MSP.ledOverlayLetters.indexOf(led.functions[overlayLetterIndex]);
|
||||||
if (bitIndex >= 0) {
|
if (bitIndex >= 0) {
|
||||||
mask |= bit_set(mask, bitIndex + 12);
|
mask |= bit_set(mask, bitIndex + 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mask |= (led.color << 18);
|
mask |= (led.color << 24);
|
||||||
|
|
||||||
for (directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
|
for (directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
|
||||||
|
|
||||||
bitIndex = MSP.ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
|
bitIndex = MSP.ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
|
||||||
if (bitIndex >= 0) {
|
if (bitIndex >= 0) {
|
||||||
mask |= bit_set(mask, bitIndex + 22);
|
if(bitIndex < 4) {
|
||||||
|
mask |= bit_set(mask, bitIndex + 28);
|
||||||
|
} else {
|
||||||
|
extra |= bit_set(extra, bitIndex - 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mask |= (0 << 28); // parameters
|
extra |= (0 << 2); // parameters
|
||||||
|
|
||||||
|
|
||||||
buffer.push(specificByte(mask, 0));
|
buffer.push(specificByte(mask, 0));
|
||||||
buffer.push(specificByte(mask, 1));
|
buffer.push(specificByte(mask, 1));
|
||||||
buffer.push(specificByte(mask, 2));
|
buffer.push(specificByte(mask, 2));
|
||||||
buffer.push(specificByte(mask, 3));
|
buffer.push(specificByte(mask, 3));
|
||||||
|
buffer.push(specificByte(extra, 0));
|
||||||
|
|
||||||
// prepare for next iteration
|
// prepare for next iteration
|
||||||
ledIndex++;
|
ledIndex++;
|
||||||
|
@ -2651,7 +2851,7 @@ var mspHelper = (function (gui) {
|
||||||
nextFunction = onCompleteCallback;
|
nextFunction = onCompleteCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_SET_LED_STRIP_CONFIG, buffer, false, nextFunction);
|
MSP.send_message(MSPCodes.MSP2_INAV_SET_LED_STRIP_CONFIG_EX, buffer, false, nextFunction);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2749,6 +2949,47 @@ var mspHelper = (function (gui) {
|
||||||
MSP.send_message(MSPCodes.MSPV2_INAV_OUTPUT_MAPPING, false, false, callback);
|
MSP.send_message(MSPCodes.MSPV2_INAV_OUTPUT_MAPPING, false, false, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.loadOutputMappingExt = function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSPV2_INAV_OUTPUT_MAPPING_EXT, false, false, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.loadTimerOutputModes = function(callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP2_INAV_TIMER_OUTPUT_MODE, false, false, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.sendTimerOutputModes = function(onCompleteCallback) {
|
||||||
|
var nextFunction = send_next_output_mode;
|
||||||
|
var idIndex = 0;
|
||||||
|
|
||||||
|
var overrideIds = OUTPUT_MAPPING.getUsedTimerIds();
|
||||||
|
|
||||||
|
if (overrideIds.length == 0) {
|
||||||
|
onCompleteCallback();
|
||||||
|
} else {
|
||||||
|
send_next_output_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
function send_next_output_mode() {
|
||||||
|
|
||||||
|
var timerId = overrideIds[idIndex];
|
||||||
|
|
||||||
|
var outputMode = OUTPUT_MAPPING.getTimerOverride(timerId);
|
||||||
|
|
||||||
|
var buffer = [];
|
||||||
|
buffer.push(timerId);
|
||||||
|
buffer.push(outputMode);
|
||||||
|
|
||||||
|
// prepare for next iteration
|
||||||
|
idIndex++;
|
||||||
|
if (idIndex == overrideIds.length) {
|
||||||
|
nextFunction = onCompleteCallback;
|
||||||
|
|
||||||
|
}
|
||||||
|
MSP.send_message(MSPCodes.MSP2_INAV_SET_TIMER_OUTPUT_MODE, buffer, false, nextFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
self.loadBatteryConfig = function (callback) {
|
self.loadBatteryConfig = function (callback) {
|
||||||
MSP.send_message(MSPCodes.MSPV2_BATTERY_CONFIG, false, false, callback);
|
MSP.send_message(MSPCodes.MSPV2_BATTERY_CONFIG, false, false, callback);
|
||||||
};
|
};
|
||||||
|
@ -2932,7 +3173,7 @@ var mspHelper = (function (gui) {
|
||||||
if (waypointId < MISSION_PLANNER.getCountBusyPoints()) {
|
if (waypointId < MISSION_PLANNER.getCountBusyPoints()) {
|
||||||
MSP.send_message(MSPCodes.MSP_WP, [waypointId], false, loadWaypoint);
|
MSP.send_message(MSPCodes.MSP_WP, [waypointId], false, loadWaypoint);
|
||||||
} else {
|
} else {
|
||||||
GUI.log('Receive time: ' + (new Date().getTime() - startTime) + 'ms');
|
GUI.log(chrome.i18n.getMessage('ReceiveTime') + (new Date().getTime() - startTime) + 'ms');
|
||||||
MSP.send_message(MSPCodes.MSP_WP, [waypointId], false, callback);
|
MSP.send_message(MSPCodes.MSP_WP, [waypointId], false, callback);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2954,7 +3195,7 @@ var mspHelper = (function (gui) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function endMission() {
|
function endMission() {
|
||||||
GUI.log('Send time: ' + (new Date().getTime() - startTime) + 'ms');
|
GUI.log(chrome.i18n.getMessage('SendTime') + (new Date().getTime() - startTime) + 'ms');
|
||||||
MSP.send_message(MSPCodes.MSP_WP_GETINFO, false, false, callback);
|
MSP.send_message(MSPCodes.MSP_WP_GETINFO, false, false, callback);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3103,6 +3344,12 @@ var mspHelper = (function (gui) {
|
||||||
|
|
||||||
self.encodeSetting = function (name, value) {
|
self.encodeSetting = function (name, value) {
|
||||||
return this._getSetting(name).then(function (setting) {
|
return this._getSetting(name).then(function (setting) {
|
||||||
|
|
||||||
|
if (!setting) {
|
||||||
|
console.log("Setting invalid: " + name);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (setting.table && !Number.isInteger(value)) {
|
if (setting.table && !Number.isInteger(value)) {
|
||||||
var found = false;
|
var found = false;
|
||||||
for (var ii = 0; ii < setting.table.values.length; ii++) {
|
for (var ii = 0; ii < setting.table.values.length; ii++) {
|
||||||
|
@ -3150,7 +3397,11 @@ var mspHelper = (function (gui) {
|
||||||
|
|
||||||
self.setSetting = function (name, value, callback) {
|
self.setSetting = function (name, value, callback) {
|
||||||
this.encodeSetting(name, value).then(function (data) {
|
this.encodeSetting(name, value).then(function (data) {
|
||||||
return MSP.promise(MSPCodes.MSPV2_SET_SETTING, data).then(callback);
|
if (data) {
|
||||||
|
return MSP.promise(MSPCodes.MSPV2_SET_SETTING, data).then(callback);
|
||||||
|
} else {
|
||||||
|
return Promise.resolve().then(callback);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3190,6 +3441,15 @@ var mspHelper = (function (gui) {
|
||||||
MSP.send_message(MSPCodes.MSP_MOTOR, false, false, callback);
|
MSP.send_message(MSPCodes.MSP_MOTOR, false, false, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.getTarget = function(callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP_FC_VERSION, false, false, function(resp){
|
||||||
|
var target = resp.data.readString();
|
||||||
|
if (callback) {
|
||||||
|
callback(target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
self.getCraftName = function (callback) {
|
self.getCraftName = function (callback) {
|
||||||
MSP.send_message(MSPCodes.MSP_NAME, false, false, function (resp) {
|
MSP.send_message(MSPCodes.MSP_NAME, false, false, function (resp) {
|
||||||
var name = resp.data.readString();
|
var name = resp.data.readString();
|
||||||
|
@ -3232,6 +3492,22 @@ var mspHelper = (function (gui) {
|
||||||
MSP.send_message(MSPCodes.MSP2_INAV_SET_MC_BRAKING, mspHelper.crunch(MSPCodes.MSP2_INAV_SET_MC_BRAKING), false, callback);
|
MSP.send_message(MSPCodes.MSP2_INAV_SET_MC_BRAKING, mspHelper.crunch(MSPCodes.MSP2_INAV_SET_MC_BRAKING), false, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.loadRateDynamics = function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP2_INAV_RATE_DYNAMICS, false, false, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.saveRateDynamics = function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP2_INAV_SET_RATE_DYNAMICS, mspHelper.crunch(MSPCodes.MSP2_INAV_SET_RATE_DYNAMICS), false, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.loadEzTune = function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP2_INAV_EZ_TUNE, false, false, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.saveEzTune = function (callback) {
|
||||||
|
MSP.send_message(MSPCodes.MSP2_INAV_EZ_TUNE_SET, mspHelper.crunch(MSPCodes.MSP2_INAV_EZ_TUNE_SET), false, callback);
|
||||||
|
}
|
||||||
|
|
||||||
self.loadParameterGroups = function (callback) {
|
self.loadParameterGroups = function (callback) {
|
||||||
MSP.send_message(MSPCodes.MSP2_COMMON_PG_LIST, false, false, function (resp) {
|
MSP.send_message(MSPCodes.MSP2_COMMON_PG_LIST, false, false, function (resp) {
|
||||||
var groups = [];
|
var groups = [];
|
||||||
|
|
|
@ -3,22 +3,63 @@
|
||||||
|
|
||||||
let OutputMappingCollection = function () {
|
let OutputMappingCollection = function () {
|
||||||
let self = {},
|
let self = {},
|
||||||
data = [];
|
data = [],
|
||||||
|
timerOverrides = {};
|
||||||
|
|
||||||
const TIM_USE_ANY = 0;
|
const TIM_USE_ANY = 0;
|
||||||
const TIM_USE_PPM = 0;
|
const TIM_USE_PPM = 0;
|
||||||
const TIM_USE_PWM = 1;
|
const TIM_USE_PWM = 1;
|
||||||
const TIM_USE_MC_MOTOR = 2; // Multicopter motor output
|
const TIM_USE_MOTOR = 2; // Motor output
|
||||||
const TIM_USE_MC_SERVO = 3; // Multicopter servo output (i.e. TRI)
|
const TIM_USE_SERVO = 3; // Servo output (i.e. TRI)
|
||||||
const TIM_USE_MC_CHNFW = 4; // Deprecated and not used after removal of CHANNEL_FORWARDING feature
|
//const TIM_USE_MC_CHNFW = 4; // Deprecated and not used after removal of CHANNEL_FORWARDING feature
|
||||||
const TIM_USE_FW_MOTOR = 5;
|
//const TIM_USE_FW_MOTOR = 5;
|
||||||
const TIM_USE_FW_SERVO = 6;
|
//const TIM_USE_FW_SERVO = 6;
|
||||||
const TIM_USE_LED = 24;
|
const TIM_USE_LED = 24;
|
||||||
const TIM_USE_BEEPER = 25;
|
const TIM_USE_BEEPER = 25;
|
||||||
|
|
||||||
const OUTPUT_TYPE_MOTOR = 0;
|
const OUTPUT_TYPE_MOTOR = 0;
|
||||||
const OUTPUT_TYPE_SERVO = 1;
|
const OUTPUT_TYPE_SERVO = 1;
|
||||||
|
|
||||||
|
self.TIMER_OUTPUT_MODE_AUTO = 0;
|
||||||
|
self.TIMER_OUTPUT_MODE_MOTORS = 1;
|
||||||
|
self.TIMER_OUTPUT_MODE_SERVOS = 2;
|
||||||
|
|
||||||
|
self.flushTimerOverrides = function() {
|
||||||
|
timerOverrides = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
self.setTimerOverride = function (timer, outputMode) {
|
||||||
|
timerOverrides[timer] = outputMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.getTimerOverride = function (timer) {
|
||||||
|
return timerOverrides[timer];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.getTimerColor = function (timer) {
|
||||||
|
let timerIndex = OUTPUT_MAPPING.getUsedTimerIds().indexOf(String(timer));
|
||||||
|
|
||||||
|
return GUI.colorTable[timerIndex % GUI.colorTable.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.getOutputTimerColor = function (output) {
|
||||||
|
let timerId = OUTPUT_MAPPING.getTimerId(output);
|
||||||
|
|
||||||
|
return self.getTimerColor(timerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.getUsedTimerIds = function (timer) {
|
||||||
|
let used = {};
|
||||||
|
let outputCount = self.getOutputCount();
|
||||||
|
|
||||||
|
for (let i = 0; i < outputCount; ++i) {
|
||||||
|
let timerId = self.getTimerId(i);
|
||||||
|
used[timerId] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.keys(used).sort((a, b) => a - b);
|
||||||
|
}
|
||||||
|
|
||||||
function getTimerMap(isMR, motors, servos) {
|
function getTimerMap(isMR, motors, servos) {
|
||||||
let timerMap = [],
|
let timerMap = [],
|
||||||
motorsToGo = motors,
|
motorsToGo = motors,
|
||||||
|
@ -27,24 +68,13 @@ let OutputMappingCollection = function () {
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
timerMap[i] = null;
|
timerMap[i] = null;
|
||||||
|
|
||||||
if (isMR) {
|
if (servosToGo > 0 && bit_check(data[i]['usageFlags'], TIM_USE_SERVO)) {
|
||||||
if (servosToGo > 0 && bit_check(data[i], TIM_USE_MC_SERVO)) {
|
servosToGo--;
|
||||||
servosToGo--;
|
timerMap[i] = OUTPUT_TYPE_SERVO;
|
||||||
timerMap[i] = OUTPUT_TYPE_SERVO;
|
} else if (motorsToGo > 0 && bit_check(data[i]['usageFlags'], TIM_USE_MOTOR)) {
|
||||||
} else if (motorsToGo > 0 && bit_check(data[i], TIM_USE_MC_MOTOR)) {
|
motorsToGo--;
|
||||||
motorsToGo--;
|
timerMap[i] = OUTPUT_TYPE_MOTOR;
|
||||||
timerMap[i] = OUTPUT_TYPE_MOTOR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (servosToGo > 0 && bit_check(data[i], TIM_USE_FW_SERVO)) {
|
|
||||||
servosToGo--;
|
|
||||||
timerMap[i] = OUTPUT_TYPE_SERVO;
|
|
||||||
} else if (motorsToGo > 0 && bit_check(data[i], TIM_USE_FW_MOTOR)) {
|
|
||||||
motorsToGo--;
|
|
||||||
timerMap[i] = OUTPUT_TYPE_MOTOR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return timerMap;
|
return timerMap;
|
||||||
|
@ -70,7 +100,6 @@ let OutputMappingCollection = function () {
|
||||||
outputMap[i] = "Servo " + servos[currentServoIndex];
|
outputMap[i] = "Servo " + servos[currentServoIndex];
|
||||||
currentServoIndex++;
|
currentServoIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return outputMap;
|
return outputMap;
|
||||||
|
@ -89,10 +118,8 @@ let OutputMappingCollection = function () {
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
if (
|
if (
|
||||||
bit_check(data[i], TIM_USE_MC_MOTOR) ||
|
bit_check(data[i]['usageFlags'], TIM_USE_MOTOR) ||
|
||||||
bit_check(data[i], TIM_USE_MC_SERVO) ||
|
bit_check(data[i]['usageFlags'], TIM_USE_SERVO)
|
||||||
bit_check(data[i], TIM_USE_FW_MOTOR) ||
|
|
||||||
bit_check(data[i], TIM_USE_FW_SERVO)
|
|
||||||
) {
|
) {
|
||||||
retVal++;
|
retVal++;
|
||||||
};
|
};
|
||||||
|
@ -104,10 +131,8 @@ let OutputMappingCollection = function () {
|
||||||
function getFirstOutputOffset() {
|
function getFirstOutputOffset() {
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
if (
|
if (
|
||||||
bit_check(data[i], TIM_USE_MC_MOTOR) ||
|
bit_check(data[i]['usageFlags'], TIM_USE_MOTOR) ||
|
||||||
bit_check(data[i], TIM_USE_MC_SERVO) ||
|
bit_check(data[i]['usageFlags'], TIM_USE_SERVO)
|
||||||
bit_check(data[i], TIM_USE_FW_MOTOR) ||
|
|
||||||
bit_check(data[i], TIM_USE_FW_SERVO)
|
|
||||||
) {
|
) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -115,6 +140,10 @@ let OutputMappingCollection = function () {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTimerId(outputIndex) {
|
||||||
|
return data[outputIndex]['timerId'];
|
||||||
|
}
|
||||||
|
|
||||||
function getOutput(servoIndex, bit) {
|
function getOutput(servoIndex, bit) {
|
||||||
|
|
||||||
let offset = getFirstOutputOffset();
|
let offset = getFirstOutputOffset();
|
||||||
|
@ -122,7 +151,7 @@ let OutputMappingCollection = function () {
|
||||||
let lastFound = 0;
|
let lastFound = 0;
|
||||||
|
|
||||||
for (let i = offset; i < data.length; i++) {
|
for (let i = offset; i < data.length; i++) {
|
||||||
if (bit_check(data[i], bit)) {
|
if (bit_check(data[i]['usageFlags'], bit)) {
|
||||||
if (lastFound == servoIndex) {
|
if (lastFound == servoIndex) {
|
||||||
return i - offset + 1;
|
return i - offset + 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -134,12 +163,16 @@ let OutputMappingCollection = function () {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.getTimerId = function(outputIndex) {
|
||||||
|
return getTimerId(outputIndex)
|
||||||
|
}
|
||||||
|
|
||||||
self.getFwServoOutput = function (servoIndex) {
|
self.getFwServoOutput = function (servoIndex) {
|
||||||
return getOutput(servoIndex, TIM_USE_FW_SERVO);
|
return getOutput(servoIndex, TIM_USE_SERVO);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getMrServoOutput = function (index) {
|
self.getMrServoOutput = function (index) {
|
||||||
return getOutput(index, TIM_USE_MC_SERVO);
|
return getOutput(index, TIM_USE_SERVO);
|
||||||
};
|
};
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -23,10 +23,15 @@ function adjustBoxNameIfPeripheralWithModeID(modeId, defaultName) {
|
||||||
case 41: // BOXCAMERA3
|
case 41: // BOXCAMERA3
|
||||||
return "CAMERA CHANGE MODE";
|
return "CAMERA CHANGE MODE";
|
||||||
default:
|
default:
|
||||||
return defaultName;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultName;
|
|
||||||
|
|
||||||
|
if (modeId === 11) {
|
||||||
|
if (FC.isAirplane()) {
|
||||||
|
return "NAV LOITER";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultName;
|
||||||
}
|
}
|
|
@ -1,7 +1,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var usbDevices = {
|
var usbDevices = {
|
||||||
STM32DFU: {'vendorId': 1155, 'productId': 57105}
|
filters: [
|
||||||
|
{'vendorId': 1155, 'productId': 57105},
|
||||||
|
{'vendorId': 11836, 'productId': 57105}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
var PortHandler = new function () {
|
var PortHandler = new function () {
|
||||||
|
@ -19,7 +22,16 @@ PortHandler.initialize = function () {
|
||||||
PortHandler.check = function () {
|
PortHandler.check = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
ConnectionSerial.getDevices(function(current_ports) {
|
ConnectionSerial.getDevices(function(all_ports) {
|
||||||
|
|
||||||
|
// filter out ports that are not serial
|
||||||
|
let current_ports = [];
|
||||||
|
for (var i = 0; i < all_ports.length; i++) {
|
||||||
|
if (all_ports[i].indexOf(':') === -1) {
|
||||||
|
current_ports.push(all_ports[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// port got removed or initial_ports wasn't initialized yet
|
// port got removed or initial_ports wasn't initialized yet
|
||||||
if (self.array_difference(self.initial_ports, current_ports).length > 0 || !self.initial_ports) {
|
if (self.array_difference(self.initial_ports, current_ports).length > 0 || !self.initial_ports) {
|
||||||
var removed_ports = self.array_difference(self.initial_ports, current_ports);
|
var removed_ports = self.array_difference(self.initial_ports, current_ports);
|
||||||
|
@ -66,7 +78,7 @@ PortHandler.check = function () {
|
||||||
chrome.storage.local.get('last_used_port', function (result) {
|
chrome.storage.local.get('last_used_port', function (result) {
|
||||||
// if last_used_port was set, we try to select it
|
// if last_used_port was set, we try to select it
|
||||||
if (result.last_used_port) {
|
if (result.last_used_port) {
|
||||||
if (result.last_used_port == "ble" || result.last_used_port == "tcp" || result.last_used_port == "udp") {
|
if (result.last_used_port == "ble" || result.last_used_port == "tcp" || result.last_used_port == "udp" || result.last_used_port == "sitl" || result.last_used_port == "sitl-demo") {
|
||||||
$('#port').val(result.last_used_port);
|
$('#port').val(result.last_used_port);
|
||||||
} else {
|
} else {
|
||||||
current_ports.forEach(function(port) {
|
current_ports.forEach(function(port) {
|
||||||
|
@ -152,7 +164,7 @@ PortHandler.check = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
PortHandler.check_usb_devices = function (callback) {
|
PortHandler.check_usb_devices = function (callback) {
|
||||||
chrome.usb.getDevices(usbDevices.STM32DFU, function (result) {
|
chrome.usb.getDevices(usbDevices, function (result) {
|
||||||
if (result.length) {
|
if (result.length) {
|
||||||
if (!$("div#port-picker #port [value='DFU']").length) {
|
if (!$("div#port-picker #port [value='DFU']").length) {
|
||||||
$('div#port-picker #port').append($('<option/>', {value: "DFU", text: "DFU", data: {isDFU: true}}));
|
$('div#port-picker #port').append($('<option/>', {value: "DFU", text: "DFU", data: {isDFU: true}}));
|
||||||
|
@ -166,7 +178,7 @@ PortHandler.check_usb_devices = function (callback) {
|
||||||
self.dfu_available = false;
|
self.dfu_available = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(callback) callback(self.dfu_available);
|
if (callback) callback(self.dfu_available);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -181,6 +193,8 @@ PortHandler.update_port_select = function (ports) {
|
||||||
$('div#port-picker #port').append($("<option/>", {value: 'ble', text: 'BLE', data: {isBle: true}}));
|
$('div#port-picker #port').append($("<option/>", {value: 'ble', text: 'BLE', data: {isBle: true}}));
|
||||||
$('div#port-picker #port').append($("<option/>", {value: 'tcp', text: 'TCP', data: {isTcp: true}}));
|
$('div#port-picker #port').append($("<option/>", {value: 'tcp', text: 'TCP', data: {isTcp: true}}));
|
||||||
$('div#port-picker #port').append($("<option/>", {value: 'udp', text: 'UDP', data: {isUdp: true}}));
|
$('div#port-picker #port').append($("<option/>", {value: 'udp', text: 'UDP', data: {isUdp: true}}));
|
||||||
|
$('div#port-picker #port').append($("<option/>", {value: 'sitl', text: 'SITL', data: {isSitl: true}}));
|
||||||
|
$('div#port-picker #port').append($("<option/>", {value: 'sitl-demo', text: 'Demo mode', data: {isSitl: true}}));
|
||||||
};
|
};
|
||||||
|
|
||||||
PortHandler.port_detected = function(name, code, timeout, ignore_timeout) {
|
PortHandler.port_detected = function(name, code, timeout, ignore_timeout) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options, callback)
|
||||||
|
|
||||||
self.initialize();
|
self.initialize();
|
||||||
} else {
|
} else {
|
||||||
GUI.log('<span style="color: red">Failed</span> to open serial port');
|
GUI.log(chrome.i18n.getMessage('failedToOpenSerialPort'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -108,14 +108,14 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options, callback)
|
||||||
retries++;
|
retries++;
|
||||||
if (retries > maxRetries) {
|
if (retries > maxRetries) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
GUI.log('<span style="color: red">Failed</span> to flash ' + port);
|
GUI.log(chrome.i18n.getMessage('failedToFlash') + port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check for DFU devices
|
// Check for DFU devices
|
||||||
PortHandler.check_usb_devices(function(dfu_available) {
|
PortHandler.check_usb_devices(function(dfu_available) {
|
||||||
if (dfu_available) {
|
if (dfu_available) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
STM32DFU.connect(usbDevices.STM32DFU, hex, options);
|
STM32DFU.connect(usbDevices, hex, options);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Check for the serial port
|
// Check for the serial port
|
||||||
|
@ -145,7 +145,7 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options, callback)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
GUI.log('<span style="color: red">Failed</span> to open serial port');
|
GUI.log(chrome.i18n.getMessage('failedToOpenSerialPort'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,6 +336,8 @@ STM32DFU_protocol.prototype.getChipInfo = function (_interface, callback) {
|
||||||
// H750 SPRacing H7 EXST: "@External Flash /0x90000000/998*128Kg,1*128Kg,4*128Kg,21*128Ka"
|
// H750 SPRacing H7 EXST: "@External Flash /0x90000000/998*128Kg,1*128Kg,4*128Kg,21*128Ka"
|
||||||
// H750 SPRacing H7 EXST: "@External Flash /0x90000000/1001*128Kg,3*128Kg,20*128Ka" - Early BL firmware with incorrect string, treat as above.
|
// H750 SPRacing H7 EXST: "@External Flash /0x90000000/1001*128Kg,3*128Kg,20*128Ka" - Early BL firmware with incorrect string, treat as above.
|
||||||
|
|
||||||
|
// AT32F435: "@Internal Flash /0x08000000/512*002Kg,@Option byte /0x1FFFC000/01*512 g"
|
||||||
|
|
||||||
// H750 Partitions: Flash, Config, Firmware, 1x BB Management block + x BB Replacement blocks)
|
// H750 Partitions: Flash, Config, Firmware, 1x BB Management block + x BB Replacement blocks)
|
||||||
if (str == "@External Flash /0x90000000/1001*128Kg,3*128Kg,20*128Ka") {
|
if (str == "@External Flash /0x90000000/1001*128Kg,3*128Kg,20*128Ka") {
|
||||||
str = "@External Flash /0x90000000/998*128Kg,1*128Kg,4*128Kg,21*128Ka";
|
str = "@External Flash /0x90000000/998*128Kg,1*128Kg,4*128Kg,21*128Ka";
|
||||||
|
@ -617,6 +619,11 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
// workaroud for AT32
|
||||||
|
if (typeof self.chipInfo.option_bytes === "undefined" && typeof self.chipInfo.option_byte !== "undefined") {
|
||||||
|
self.chipInfo.option_bytes = self.chipInfo.option_byte;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof self.chipInfo.option_bytes === "undefined") {
|
if (typeof self.chipInfo.option_bytes === "undefined") {
|
||||||
console.log('Failed to detect option bytes');
|
console.log('Failed to detect option bytes');
|
||||||
self.cleanup();
|
self.cleanup();
|
||||||
|
|
|
@ -5,7 +5,8 @@ $(document).ready(function () {
|
||||||
|
|
||||||
var $port = $('#port'),
|
var $port = $('#port'),
|
||||||
$baud = $('#baud'),
|
$baud = $('#baud'),
|
||||||
$portOverride = $('#port-override');
|
$portOverride = $('#port-override'),
|
||||||
|
isDemoRunning = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle "Wireless" mode with strict queueing of messages
|
* Handle "Wireless" mode with strict queueing of messages
|
||||||
|
@ -89,14 +90,14 @@ $(document).ready(function () {
|
||||||
$('#port-override-label').text("Port");
|
$('#port-override-label').text("Port");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected_port.data().isDFU || selected_port.data().isBle || selected_port.data().isTcp || selected_port.data().isUdp) {
|
if (selected_port.data().isDFU || selected_port.data().isBle || selected_port.data().isTcp || selected_port.data().isUdp || selected_port.data().isSitl) {
|
||||||
$baud.hide();
|
$baud.hide();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$baud.show();
|
$baud.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected_port.data().isBle || selected_port.data().isTcp || selected_port.data().isUdp) {
|
if (selected_port.data().isBle || selected_port.data().isTcp || selected_port.data().isUdp || selected_port.data().isSitl) {
|
||||||
$('.tab_firmware_flasher').hide();
|
$('.tab_firmware_flasher').hide();
|
||||||
} else {
|
} else {
|
||||||
$('.tab_firmware_flasher').show();
|
$('.tab_firmware_flasher').show();
|
||||||
|
@ -104,7 +105,7 @@ $(document).ready(function () {
|
||||||
var type = ConnectionType.Serial;
|
var type = ConnectionType.Serial;
|
||||||
if (selected_port.data().isBle) {
|
if (selected_port.data().isBle) {
|
||||||
type = ConnectionType.BLE;
|
type = ConnectionType.BLE;
|
||||||
} else if (selected_port.data().isTcp) {
|
} else if (selected_port.data().isTcp || selected_port.data().isSitl) {
|
||||||
type = ConnectionType.TCP;
|
type = ConnectionType.TCP;
|
||||||
} else if (selected_port.data().isUdp) {
|
} else if (selected_port.data().isUdp) {
|
||||||
type = ConnectionType.UDP;
|
type = ConnectionType.UDP;
|
||||||
|
@ -150,10 +151,24 @@ $(document).ready(function () {
|
||||||
|
|
||||||
if (selected_port == 'tcp' || selected_port == 'udp') {
|
if (selected_port == 'tcp' || selected_port == 'udp') {
|
||||||
CONFIGURATOR.connection.connect($portOverride.val(), {}, onOpen);
|
CONFIGURATOR.connection.connect($portOverride.val(), {}, onOpen);
|
||||||
|
} else if (selected_port == 'sitl') {
|
||||||
|
CONFIGURATOR.connection.connect("127.0.0.1:5760", {}, onOpen);
|
||||||
|
} else if (selected_port == 'sitl-demo') {
|
||||||
|
if (SITLProcess.isRunning) {
|
||||||
|
SITLProcess.stop();
|
||||||
|
}
|
||||||
|
SITLProcess.start("demo.bin");
|
||||||
|
this.isDemoRunning = true;
|
||||||
|
CONFIGURATOR.connection.connect("127.0.0.1:5760", {}, onOpen);
|
||||||
} else {
|
} else {
|
||||||
CONFIGURATOR.connection.connect(selected_port, {bitrate: selected_baud}, onOpen);
|
CONFIGURATOR.connection.connect(selected_port, {bitrate: selected_baud}, onOpen);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (this.isDemoRunning) {
|
||||||
|
SITLProcess.stop();
|
||||||
|
this.isDemoRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
var wasConnected = CONFIGURATOR.connectionValid;
|
var wasConnected = CONFIGURATOR.connectionValid;
|
||||||
|
|
||||||
helper.timeout.killAll();
|
helper.timeout.killAll();
|
||||||
|
@ -242,6 +257,7 @@ function onValidFirmware()
|
||||||
|
|
||||||
$('#tabs ul.mode-connected .tab_setup a').click();
|
$('#tabs ul.mode-connected .tab_setup a').click();
|
||||||
|
|
||||||
|
updateEzTuneTabVisibility(true);
|
||||||
updateFirmwareVersion();
|
updateFirmwareVersion();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -464,7 +480,6 @@ function sensor_status_ex(hw_status)
|
||||||
sensor_status_update_icon('.sonar', '.sonaricon', hw_status.rangeHwStatus);
|
sensor_status_update_icon('.sonar', '.sonaricon', hw_status.rangeHwStatus);
|
||||||
sensor_status_update_icon('.airspeed', '.airspeedicon', hw_status.speedHwStatus);
|
sensor_status_update_icon('.airspeed', '.airspeedicon', hw_status.speedHwStatus);
|
||||||
sensor_status_update_icon('.opflow', '.opflowicon', hw_status.flowHwStatus);
|
sensor_status_update_icon('.opflow', '.opflowicon', hw_status.flowHwStatus);
|
||||||
sensor_status_update_icon('.imu2', '.imu2icon', hw_status.imu2HwStatus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sensor_status_update_icon(sensId, sensIconId, status)
|
function sensor_status_update_icon(sensId, sensIconId, status)
|
||||||
|
@ -499,8 +514,7 @@ function sensor_status_hash(hw_status)
|
||||||
hw_status.gpsHwStatus +
|
hw_status.gpsHwStatus +
|
||||||
hw_status.rangeHwStatus +
|
hw_status.rangeHwStatus +
|
||||||
hw_status.speedHwStatus +
|
hw_status.speedHwStatus +
|
||||||
hw_status.flowHwStatus +
|
hw_status.flowHwStatus;
|
||||||
hw_status.imu2HwStatus;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -523,7 +537,6 @@ function sensor_status(sensors_detected) {
|
||||||
SENSOR_STATUS.rangeHwStatus = have_sensor(sensors_detected, 'sonar') ? 1 : 0;
|
SENSOR_STATUS.rangeHwStatus = have_sensor(sensors_detected, 'sonar') ? 1 : 0;
|
||||||
SENSOR_STATUS.speedHwStatus = have_sensor(sensors_detected, 'airspeed') ? 1 : 0;
|
SENSOR_STATUS.speedHwStatus = have_sensor(sensors_detected, 'airspeed') ? 1 : 0;
|
||||||
SENSOR_STATUS.flowHwStatus = have_sensor(sensors_detected, 'opflow') ? 1 : 0;
|
SENSOR_STATUS.flowHwStatus = have_sensor(sensors_detected, 'opflow') ? 1 : 0;
|
||||||
SENSOR_STATUS.imu2HwStatus = have_sensor(sensors_detected, 'imu2') ? 1 : 0;
|
|
||||||
sensor_status_ex(SENSOR_STATUS);
|
sensor_status_ex(SENSOR_STATUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ let ServoMixerRuleCollection = function () {
|
||||||
|
|
||||||
let self = {},
|
let self = {},
|
||||||
data = [],
|
data = [],
|
||||||
|
inactiveData = [],
|
||||||
maxServoCount = 16;
|
maxServoCount = 16;
|
||||||
|
|
||||||
self.setServoCount = function (value) {
|
self.setServoCount = function (value) {
|
||||||
|
@ -20,7 +21,11 @@ let ServoMixerRuleCollection = function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.put = function (element) {
|
self.put = function (element) {
|
||||||
data.push(element);
|
if (data.length < self.getServoRulesCount()) {
|
||||||
|
data.push(element);
|
||||||
|
}else{
|
||||||
|
inactiveData.push(element); //store the data for mixer_profile 2
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.get = function () {
|
self.get = function () {
|
||||||
|
@ -34,18 +39,24 @@ let ServoMixerRuleCollection = function () {
|
||||||
|
|
||||||
self.flush = function () {
|
self.flush = function () {
|
||||||
data = [];
|
data = [];
|
||||||
|
inactiveData = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
self.cleanup = function () {
|
self.cleanup = function () {
|
||||||
var tmpData = [];
|
var tmpData = [];
|
||||||
|
var tmpInactiveData = [];
|
||||||
data.forEach(function (element) {
|
data.forEach(function (element) {
|
||||||
if (element.isUsed()) {
|
if (element.isUsed()) {
|
||||||
tmpData.push(element);
|
tmpData.push(element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
inactiveData.forEach(function (element) {
|
||||||
|
if (element.isUsed()) {
|
||||||
|
tmpInactiveData.push(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
data = tmpData;
|
data = tmpData;
|
||||||
|
inactiveData = tmpInactiveData;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.inflate = function () {
|
self.inflate = function () {
|
||||||
|
@ -69,6 +80,15 @@ let ServoMixerRuleCollection = function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (let ruleIndex in inactiveData) {
|
||||||
|
if (inactiveData.hasOwnProperty(ruleIndex)) {
|
||||||
|
let rule = inactiveData[ruleIndex];
|
||||||
|
|
||||||
|
if (rule.getTarget() == servoId && rule.isUsed()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,12 +126,17 @@ let ServoMixerRuleCollection = function () {
|
||||||
out.push(rule.getTarget());
|
out.push(rule.getTarget());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (let ruleIndex in inactiveData) {
|
||||||
|
if (inactiveData.hasOwnProperty(ruleIndex)) {
|
||||||
|
let rule = inactiveData[ruleIndex];
|
||||||
|
out.push(rule.getTarget());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let unique = [...new Set(out)];
|
|
||||||
|
|
||||||
return unique.sort(function(a, b) {
|
let minIndex = Math.min(...out);
|
||||||
return a-b;
|
let maxIndex = Math.max(...out);
|
||||||
});
|
return Array.from({ length: maxIndex - minIndex + 1 }, (_, index) => minIndex + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.getNextUnusedIndex = function() {
|
self.getNextUnusedIndex = function() {
|
||||||
|
|
384
js/settings.js
|
@ -3,6 +3,24 @@
|
||||||
var Settings = (function () {
|
var Settings = (function () {
|
||||||
let self = {};
|
let self = {};
|
||||||
|
|
||||||
|
self.fillSelectOption = function(s, ii) {
|
||||||
|
var name = (s.setting.table ? s.setting.table.values[ii] : null);
|
||||||
|
if (name) {
|
||||||
|
var localizedName = chrome.i18n.getMessage(name);
|
||||||
|
if (localizedName) {
|
||||||
|
name = localizedName;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback to the number itself
|
||||||
|
name = ii;
|
||||||
|
}
|
||||||
|
var option = $('<option/>').attr('value', ii).text(name);
|
||||||
|
if (ii == s.value) {
|
||||||
|
option.prop('selected', true);
|
||||||
|
}
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
|
||||||
self.configureInputs = function() {
|
self.configureInputs = function() {
|
||||||
var inputs = [];
|
var inputs = [];
|
||||||
$('[data-setting!=""][data-setting]').each(function() {
|
$('[data-setting!=""][data-setting]').each(function() {
|
||||||
|
@ -45,22 +63,21 @@ var Settings = (function () {
|
||||||
input.prop('checked', s.value > 0);
|
input.prop('checked', s.value > 0);
|
||||||
} else {
|
} else {
|
||||||
input.empty();
|
input.empty();
|
||||||
for (var ii = s.setting.min; ii <= s.setting.max; ii++) {
|
let option = null;
|
||||||
var name = (s.setting.table ? s.setting.table.values[ii] : null);
|
if (input.data('setting-invert-select') === true) {
|
||||||
if (name) {
|
for (var ii = s.setting.max; ii >= s.setting.min; ii--) {
|
||||||
var localizedName = chrome.i18n.getMessage(name);
|
option = null;
|
||||||
if (localizedName) {
|
option = self.fillSelectOption(s, ii);
|
||||||
name = localizedName;
|
|
||||||
}
|
option.appendTo(input);
|
||||||
} else {
|
|
||||||
// Fallback to the number itself
|
|
||||||
name = ii;
|
|
||||||
}
|
}
|
||||||
var option = $('<option/>').attr('value', ii).text(name);
|
} else {
|
||||||
if (ii == s.value) {
|
for (var ii = s.setting.min; ii <= s.setting.max; ii++) {
|
||||||
option.prop('selected', true);
|
option = null;
|
||||||
|
option = self.fillSelectOption(s, ii);
|
||||||
|
|
||||||
|
option.appendTo(input);
|
||||||
}
|
}
|
||||||
option.appendTo(input);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (s.setting.type == 'string') {
|
} else if (s.setting.type == 'string') {
|
||||||
|
@ -68,107 +85,27 @@ var Settings = (function () {
|
||||||
input.attr('maxlength', s.setting.max);
|
input.attr('maxlength', s.setting.max);
|
||||||
} else if (input.data('presentation') == 'range') {
|
} else if (input.data('presentation') == 'range') {
|
||||||
|
|
||||||
let scaledMax;
|
GUI.sliderize(input, s.value, s.setting.min, s.setting.max);
|
||||||
let scaledMin;
|
|
||||||
let scalingThreshold;
|
|
||||||
|
|
||||||
if (input.data('normal-max')) {
|
|
||||||
scaledMax = s.setting.max * 2;
|
|
||||||
scalingThreshold = Math.round(scaledMax * 0.8);
|
|
||||||
scaledMin = s.setting.min *2;
|
|
||||||
} else {
|
|
||||||
scaledMax = s.setting.max;
|
|
||||||
scaledMin = s.setting.min;
|
|
||||||
scalingThreshold = scaledMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let $range = $('<input type="range" min="' + scaledMin + '" max="' + scaledMax + '" value="' + s.value + '"/>');
|
|
||||||
if (input.data('step')) {
|
|
||||||
$range.attr('step', input.data('step'));
|
|
||||||
}
|
|
||||||
$range.css({
|
|
||||||
'display': 'block',
|
|
||||||
'flex-grow': 100,
|
|
||||||
'margin-left': '1em',
|
|
||||||
'margin-right': '1em',
|
|
||||||
});
|
|
||||||
|
|
||||||
input.attr('min', s.setting.min);
|
|
||||||
input.attr('max', s.setting.max);
|
|
||||||
input.val(parseInt(s.value));
|
|
||||||
input.css({
|
|
||||||
'width': 'auto',
|
|
||||||
'min-width': '75px',
|
|
||||||
});
|
|
||||||
|
|
||||||
input.parent().css({
|
|
||||||
'display': 'flex',
|
|
||||||
'width': '100%'
|
|
||||||
});
|
|
||||||
$range.insertAfter(input);
|
|
||||||
|
|
||||||
input.parent().find('.helpicon').css({
|
|
||||||
'top': '5px',
|
|
||||||
'left': '-10px'
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update slider to input
|
|
||||||
*/
|
|
||||||
$range.on('input', function() {
|
|
||||||
let val = $(this).val();
|
|
||||||
let normalMax = parseInt(input.data('normal-max'));
|
|
||||||
|
|
||||||
if (normalMax) {
|
|
||||||
if (val <= scalingThreshold) {
|
|
||||||
val = scaleRangeInt(val, scaledMin, scalingThreshold, s.setting.min, normalMax);
|
|
||||||
} else {
|
|
||||||
val = scaleRangeInt(val, scalingThreshold + 1, scaledMax, normalMax + 1, s.setting.max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input.val(val);
|
|
||||||
});
|
|
||||||
|
|
||||||
input.on('change', function() {
|
|
||||||
|
|
||||||
let val = $(this).val();
|
|
||||||
let newVal;
|
|
||||||
let normalMax = parseInt(input.data('normal-max'));
|
|
||||||
if (normalMax) {
|
|
||||||
if (val <= normalMax) {
|
|
||||||
newVal = scaleRangeInt(val, s.setting.min, normalMax, scaledMin, scalingThreshold);
|
|
||||||
} else {
|
|
||||||
newVal = scaleRangeInt(val, normalMax + 1, s.setting.max, scalingThreshold + 1, scaledMax);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
newVal = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
$range.val(newVal);
|
|
||||||
});
|
|
||||||
|
|
||||||
input.trigger('change');
|
|
||||||
|
|
||||||
} else if (s.setting.type == 'float') {
|
} else if (s.setting.type == 'float') {
|
||||||
input.attr('type', 'number');
|
input.attr('type', 'number');
|
||||||
|
|
||||||
let dataStep = input.data("step");
|
let dataStep = input.data("step");
|
||||||
|
|
||||||
if (dataStep !== undefined) {
|
if (typeof dataStep === 'undefined') {
|
||||||
input.attr('step', dataStep);
|
dataStep = self.countDecimals(s.value);
|
||||||
} else {
|
dataStep = 1 / Math.pow(10, dataStep);
|
||||||
input.attr('step', "0.01");
|
input.data("step", dataStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.attr('step', dataStep);
|
||||||
input.attr('min', s.setting.min);
|
input.attr('min', s.setting.min);
|
||||||
input.attr('max', s.setting.max);
|
input.attr('max', s.setting.max);
|
||||||
input.val(s.value.toFixed(2));
|
input.val(s.value.toFixed(self.countDecimals(dataStep)));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var multiplier = parseFloat(input.data('setting-multiplier') || 1);
|
var multiplier = parseFloat(input.data('setting-multiplier') || 1);
|
||||||
|
|
||||||
|
input.data("step", 1);
|
||||||
input.val((s.value / multiplier).toFixed(Math.log10(multiplier)));
|
input.val((s.value / multiplier).toFixed(Math.log10(multiplier)));
|
||||||
input.attr('type', 'number');
|
input.attr('type', 'number');
|
||||||
if (typeof s.setting.min !== 'undefined' && s.setting.min !== null) {
|
if (typeof s.setting.min !== 'undefined' && s.setting.min !== null) {
|
||||||
|
@ -233,47 +170,101 @@ var Settings = (function () {
|
||||||
|
|
||||||
const oldValue = element.val();
|
const oldValue = element.val();
|
||||||
|
|
||||||
//display names for the units
|
// Display names for the units
|
||||||
const unitDisplayDames = {
|
const unitDisplayNames = {
|
||||||
// Misc
|
// Misc
|
||||||
'us' : "uS",
|
|
||||||
'cw' : 'cW',
|
'cw' : 'cW',
|
||||||
'percent' : '%',
|
'percent' : '%',
|
||||||
'cmss' : 'cm/s/s',
|
'cmss' : 'cm/s/s',
|
||||||
// Time
|
// Time
|
||||||
'msec' : 'ms',
|
'us' : "uS",
|
||||||
'dsec' : 'ds',
|
'msec' : 'ms',
|
||||||
'sec' : 's',
|
'msec-nc' : 'ms', // Milliseconds, but not converted.
|
||||||
|
'dsec' : 'ds',
|
||||||
|
'sec' : 's',
|
||||||
|
'mins' : 'm',
|
||||||
|
'hours' : 'h',
|
||||||
|
'tzmins' : 'm',
|
||||||
|
'tzhours' : 'hh:mm',
|
||||||
// Angles
|
// Angles
|
||||||
'deg' : '°',
|
'centideg' : 'centi°',
|
||||||
'decideg' : 'deci°',
|
'centideg-deg' : 'centi°', // Centidegrees, but always converted to degrees by default
|
||||||
'decideg-lrg' : 'deci°', // Decidegrees, but always converted to degrees by default
|
'deg' : '°',
|
||||||
|
'decideg' : 'deci°',
|
||||||
|
'decideg-lrg' : 'deci°', // Decidegrees, but always converted to degrees by default
|
||||||
// Rotational speed
|
// Rotational speed
|
||||||
'degps' : '° per second',
|
'degps' : '° per second',
|
||||||
'decadegps' : 'deca° per second',
|
'decadegps' : 'deca° per second',
|
||||||
// Temperature
|
// Temperature
|
||||||
'decidegc' : 'deci°C',
|
'decidegc' : 'deci°C',
|
||||||
'degc' : '°C',
|
'degc' : '°C',
|
||||||
'degf' : '°F',
|
'degf' : '°F',
|
||||||
// Speed
|
// Speed
|
||||||
'cms' : 'cm/s',
|
'cms' : 'cm/s',
|
||||||
'v-cms' : 'cm/s',
|
'v-cms' : 'cm/s',
|
||||||
'ms' : 'm/s',
|
'ms' : 'm/s',
|
||||||
'kmh' : 'Km/h',
|
'kmh' : 'Km/h',
|
||||||
'mph' : 'mph',
|
'mph' : 'mph',
|
||||||
'hftmin' : 'x100 ft/min',
|
'hftmin' : 'x100 ft/min',
|
||||||
'fts' : 'ft/s',
|
'fts' : 'ft/s',
|
||||||
'kt' : 'Kt',
|
'kt' : 'Kt',
|
||||||
// Distance
|
// Distance
|
||||||
'cm' : 'cm',
|
'cm' : 'cm',
|
||||||
'm' : 'm',
|
'm' : 'm',
|
||||||
'km' : 'Km',
|
'km' : 'Km',
|
||||||
'm-lrg' : 'm', // Metres, but converted to larger units
|
'm-lrg' : 'm', // Metres, but converted to larger units
|
||||||
'ft' : 'ft',
|
'ft' : 'ft',
|
||||||
'mi' : 'mi',
|
'mi' : 'mi',
|
||||||
'nm' : 'NM'
|
'nm' : 'NM'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hover full descriptions for the units
|
||||||
|
const unitExpandedNames = {
|
||||||
|
// Misc
|
||||||
|
'cw' : 'CentiWatts',
|
||||||
|
'percent' : 'Percent',
|
||||||
|
'cmss' : 'Centimetres per second, per second',
|
||||||
|
// Time
|
||||||
|
'us' : "Microseconds",
|
||||||
|
'msec' : 'Milliseconds',
|
||||||
|
'msec-nc' : 'Milliseconds',
|
||||||
|
'dsec' : 'Deciseconds',
|
||||||
|
'sec' : 'Seconds',
|
||||||
|
'mins' : 'Minutes',
|
||||||
|
'hours' : 'Hours',
|
||||||
|
'tzmins' : 'Minutes',
|
||||||
|
'tzhours' : 'Hours:Minutes',
|
||||||
|
// Angles
|
||||||
|
'centideg' : 'CentiDegrees',
|
||||||
|
'centideg-deg' : 'CentiDegrees',
|
||||||
|
'deg' : 'Degrees',
|
||||||
|
'decideg' : 'DeciDegrees',
|
||||||
|
'decideg-lrg' : 'DeciDegrees',
|
||||||
|
// Rotational speed
|
||||||
|
'degps' : 'Degrees per second',
|
||||||
|
'decadegps' : 'DecaDegrees per second',
|
||||||
|
// Temperature
|
||||||
|
'decidegc' : 'DeciDegrees Celsius',
|
||||||
|
'degc' : 'Degrees Celsius',
|
||||||
|
'degf' : 'Degrees Fahrenheit',
|
||||||
|
// Speed
|
||||||
|
'cms' : 'Centimetres per second',
|
||||||
|
'v-cms' : 'Centimetres per second',
|
||||||
|
'ms' : 'Metres per second',
|
||||||
|
'kmh' : 'Kilometres per hour',
|
||||||
|
'mph' : 'Miles per hour',
|
||||||
|
'hftmin' : 'Hundred feet per minute',
|
||||||
|
'fts' : 'Feet per second',
|
||||||
|
'kt' : 'Knots',
|
||||||
|
// Distance
|
||||||
|
'cm' : 'Centimetres',
|
||||||
|
'm' : 'Metres',
|
||||||
|
'km' : 'Kilometres',
|
||||||
|
'm-lrg' : 'Metres',
|
||||||
|
'ft' : 'Feet',
|
||||||
|
'mi' : 'Miles',
|
||||||
|
'nm' : 'Nautical Miles'
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure we can do conversions
|
// Ensure we can do conversions
|
||||||
if (!inputUnit || !oldValue || !element) {
|
if (!inputUnit || !oldValue || !element) {
|
||||||
|
@ -309,12 +300,27 @@ var Settings = (function () {
|
||||||
'hftmin' : 50.8,
|
'hftmin' : 50.8,
|
||||||
'fts' : 30.48
|
'fts' : 30.48
|
||||||
},
|
},
|
||||||
|
'msec-nc' : {
|
||||||
|
'msec-nc' : 1
|
||||||
|
},
|
||||||
'msec' : {
|
'msec' : {
|
||||||
'sec' : 1000
|
'sec' : 1000
|
||||||
},
|
},
|
||||||
'dsec' : {
|
'dsec' : {
|
||||||
'sec' : 10
|
'sec' : 10
|
||||||
},
|
},
|
||||||
|
'mins' : {
|
||||||
|
'hours' : 60
|
||||||
|
},
|
||||||
|
'tzmins' : {
|
||||||
|
'tzhours' : 'TZHOURS'
|
||||||
|
},
|
||||||
|
'centideg' : {
|
||||||
|
'deg' : 0.1
|
||||||
|
},
|
||||||
|
'centideg-deg' : {
|
||||||
|
'deg' : 0.1
|
||||||
|
},
|
||||||
'decideg' : {
|
'decideg' : {
|
||||||
'deg' : 10
|
'deg' : 10
|
||||||
},
|
},
|
||||||
|
@ -340,7 +346,11 @@ var Settings = (function () {
|
||||||
'v-cms' : 'fts',
|
'v-cms' : 'fts',
|
||||||
'msec' : 'sec',
|
'msec' : 'sec',
|
||||||
'dsec' : 'sec',
|
'dsec' : 'sec',
|
||||||
|
'mins' : 'hours',
|
||||||
|
'tzmins' : 'tzhours',
|
||||||
'decadegps' : 'degps',
|
'decadegps' : 'degps',
|
||||||
|
'centideg' : 'deg',
|
||||||
|
'centideg-deg' : 'deg',
|
||||||
'decideg' : 'deg',
|
'decideg' : 'deg',
|
||||||
'decideg-lrg' : 'deg',
|
'decideg-lrg' : 'deg',
|
||||||
'decidegc' : 'degf',
|
'decidegc' : 'degf',
|
||||||
|
@ -353,7 +363,11 @@ var Settings = (function () {
|
||||||
'v-cms' : 'ms',
|
'v-cms' : 'ms',
|
||||||
'msec' : 'sec',
|
'msec' : 'sec',
|
||||||
'dsec' : 'sec',
|
'dsec' : 'sec',
|
||||||
|
'mins' : 'hours',
|
||||||
|
'tzmins' : 'tzhours',
|
||||||
'decadegps' : 'degps',
|
'decadegps' : 'degps',
|
||||||
|
'centideg' : 'deg',
|
||||||
|
'centideg-deg' : 'deg',
|
||||||
'decideg' : 'deg',
|
'decideg' : 'deg',
|
||||||
'decideg-lrg' : 'deg',
|
'decideg-lrg' : 'deg',
|
||||||
'decidegc' : 'degc',
|
'decidegc' : 'degc',
|
||||||
|
@ -365,10 +379,14 @@ var Settings = (function () {
|
||||||
'cms' : 'mph',
|
'cms' : 'mph',
|
||||||
'v-cms' : 'ms',
|
'v-cms' : 'ms',
|
||||||
'decadegps' : 'degps',
|
'decadegps' : 'degps',
|
||||||
|
'centideg' : 'deg',
|
||||||
|
'centideg-deg' : 'deg',
|
||||||
'decideg' : 'deg',
|
'decideg' : 'deg',
|
||||||
'decideg-lrg' : 'deg',
|
'decideg-lrg' : 'deg',
|
||||||
'msec' : 'sec',
|
'msec' : 'sec',
|
||||||
'dsec' : 'sec',
|
'dsec' : 'sec',
|
||||||
|
'mins' : 'hours',
|
||||||
|
'tzmins' : 'tzhours',
|
||||||
'decidegc' : 'degc',
|
'decidegc' : 'degc',
|
||||||
},
|
},
|
||||||
3:{ //UK
|
3:{ //UK
|
||||||
|
@ -377,11 +395,15 @@ var Settings = (function () {
|
||||||
'm-lrg' : 'mi',
|
'm-lrg' : 'mi',
|
||||||
'cms' : 'mph',
|
'cms' : 'mph',
|
||||||
'v-cms' : 'fts',
|
'v-cms' : 'fts',
|
||||||
'decadegps' : 'degpd',
|
'decadegps' : 'degps',
|
||||||
|
'centideg' : 'deg',
|
||||||
|
'centideg-deg' : 'deg',
|
||||||
'decideg' : 'deg',
|
'decideg' : 'deg',
|
||||||
'decideg-lrg' : 'deg',
|
'decideg-lrg' : 'deg',
|
||||||
'msec' : 'sec',
|
'msec' : 'sec',
|
||||||
'dsec' : 'sec',
|
'dsec' : 'sec',
|
||||||
|
'mins' : 'hours',
|
||||||
|
'tzmins' : 'tzhours',
|
||||||
'decidegc' : 'degc',
|
'decidegc' : 'degc',
|
||||||
},
|
},
|
||||||
4: { //General aviation
|
4: { //General aviation
|
||||||
|
@ -391,15 +413,22 @@ var Settings = (function () {
|
||||||
'cms': 'kt',
|
'cms': 'kt',
|
||||||
'v-cms' : 'hftmin',
|
'v-cms' : 'hftmin',
|
||||||
'decadegps' : 'degps',
|
'decadegps' : 'degps',
|
||||||
|
'centideg' : 'deg',
|
||||||
|
'centideg-deg' : 'deg',
|
||||||
'decideg' : 'deg',
|
'decideg' : 'deg',
|
||||||
'decideg-lrg' : 'deg',
|
'decideg-lrg' : 'deg',
|
||||||
'msec' : 'sec',
|
'msec' : 'sec',
|
||||||
'dsec' : 'sec',
|
'dsec' : 'sec',
|
||||||
|
'mins' : 'hours',
|
||||||
|
'tzmins' : 'tzhours',
|
||||||
'decidegc' : 'degc',
|
'decidegc' : 'degc',
|
||||||
},
|
},
|
||||||
default: { //show base units
|
default: { //show base units
|
||||||
'decadegps' : 'degps',
|
'decadegps' : 'degps',
|
||||||
'decideg-lrg' : 'deg',
|
'decideg-lrg' : 'deg',
|
||||||
|
'centideg' : 'deg',
|
||||||
|
'centideg-deg' : 'deg',
|
||||||
|
'tzmins' : 'tzhours',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -423,43 +452,51 @@ var Settings = (function () {
|
||||||
const multiplier = multiObj.multiplier;
|
const multiplier = multiObj.multiplier;
|
||||||
const unitName = multiObj.unitName;
|
const unitName = multiObj.unitName;
|
||||||
|
|
||||||
|
let decimalPlaces = 0;
|
||||||
// Update the step, min, and max; as we have the multiplier here.
|
// Update the step, min, and max; as we have the multiplier here.
|
||||||
if (element.attr('type') == 'number') {
|
if (element.attr('type') == 'number') {
|
||||||
let step = element.attr('step') || 1;
|
let step = parseFloat(element.attr('step')) || 1;
|
||||||
let decimalPlaces = 0;
|
|
||||||
|
|
||||||
step = step / multiplier;
|
if (multiplier !== 1) {
|
||||||
|
decimalPlaces = Math.min(Math.ceil(multiplier / 100), 3);
|
||||||
if (step < 1) {
|
// Add extra decimal place for non-integer conversions.
|
||||||
decimalPlaces = step.toString().length - step.toString().indexOf(".") - 1;
|
if (multiplier % 1 != 0 && decimalPlaces < 3) {
|
||||||
if (parseInt(step.toString().slice(-1)) > 1 ) {
|
decimalPlaces++;
|
||||||
decimalPlaces--;
|
|
||||||
}
|
}
|
||||||
step = 1 / Math.pow(10, decimalPlaces);
|
step = 1 / Math.pow(10, decimalPlaces);
|
||||||
}
|
}
|
||||||
element.attr('step', step.toFixed(decimalPlaces));
|
element.attr('step', step.toFixed(decimalPlaces));
|
||||||
|
|
||||||
if (multiplier != 'FAHREN') {
|
if (multiplier !== 'FAHREN' && multiplier !== 'TZHOURS' && multiplier !== 1) {
|
||||||
element.attr('min', (element.attr('min') / multiplier).toFixed(decimalPlaces));
|
element.data('default-min', element.attr('min'));
|
||||||
element.attr('max', (element.attr('max') / multiplier).toFixed(decimalPlaces));
|
element.data('default-max', element.attr('max'));
|
||||||
|
element.attr('min', (parseFloat(element.attr('min')) / multiplier).toFixed(decimalPlaces));
|
||||||
|
element.attr('max', (parseFloat(element.attr('max')) / multiplier).toFixed(decimalPlaces));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the input with a new formatted unit
|
// Update the input with a new formatted unit
|
||||||
let newValue = "";
|
let newValue = "";
|
||||||
if (multiplier == 'FAHREN') {
|
if (multiplier === 'FAHREN') {
|
||||||
element.attr('min', toFahrenheit(element.attr('min')).toFixed(2));
|
element.attr('min', toFahrenheit(element.attr('min')).toFixed(decimalPlaces));
|
||||||
element.attr('max', toFahrenheit(element.attr('max')).toFixed(2));
|
element.attr('max', toFahrenheit(element.attr('max')).toFixed(decimalPlaces));
|
||||||
newValue = toFahrenheit(oldValue).toFixed(2);
|
newValue = toFahrenheit(oldValue).toFixed(decimalPlaces);
|
||||||
|
} else if (multiplier === 'TZHOURS') {
|
||||||
|
element.attr('type', 'text');
|
||||||
|
element.removeAttr('step');
|
||||||
|
element.attr('pattern', '([0-9]{2}|[-,0-9]{3}):([0-9]{2})');
|
||||||
|
let hours = Math.floor(oldValue/60);
|
||||||
|
let mins = oldValue - (hours*60);
|
||||||
|
newValue = ((hours < 0) ? padZeros(hours, 3) : padZeros(hours, 2)) + ':' + padZeros(mins, 2);
|
||||||
} else {
|
} else {
|
||||||
const convertedValue = Number((oldValue / multiplier).toFixed(2));
|
newValue = Number((oldValue / multiplier)).toFixed(decimalPlaces);
|
||||||
newValue = Number.isInteger(convertedValue) ? Math.round(convertedValue) : convertedValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
element.val(newValue);
|
element.val(newValue);
|
||||||
element.data('setting-multiplier', multiplier);
|
element.data('setting-multiplier', multiplier);
|
||||||
|
|
||||||
// Now wrap the input in a display that shows the unit
|
// Now wrap the input in a display that shows the unit
|
||||||
element.wrap(`<div data-unit="${unitDisplayDames[unitName]}" class="unit_wrapper unit"></div>`);
|
element.wrap(`<div data-unit="${unitDisplayNames[unitName]}" title="${unitExpandedNames[unitName]}" class="unit_wrapper unit"></div>`);
|
||||||
|
|
||||||
function toFahrenheit(decidegC) {
|
function toFahrenheit(decidegC) {
|
||||||
return (decidegC / 10) * 1.8 + 32;
|
return (decidegC / 10) * 1.8 + 32;
|
||||||
|
@ -487,14 +524,57 @@ var Settings = (function () {
|
||||||
var multiplier = input.data('setting-multiplier') || 1;
|
var multiplier = input.data('setting-multiplier') || 1;
|
||||||
if (multiplier == 'FAHREN') {
|
if (multiplier == 'FAHREN') {
|
||||||
value = Math.round(((parseFloat(input.val())-32) / 1.8) * 10);
|
value = Math.round(((parseFloat(input.val())-32) / 1.8) * 10);
|
||||||
|
} else if (multiplier === 'TZHOURS') {
|
||||||
|
let inputTZ = input.val().split(':');
|
||||||
|
value = (parseInt(inputTZ[0]) * 60) + parseInt(inputTZ[1]);
|
||||||
|
|
||||||
|
if (value > parseInt(input.attr('max'))) {
|
||||||
|
value = parseInt(input.attr('max'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < parseInt(input.attr('min'))) {
|
||||||
|
value = parseInt(input.attr('min'));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
multiplier = parseFloat(multiplier);
|
multiplier = parseFloat(multiplier);
|
||||||
value = Math.round(parseFloat(input.val()) * multiplier);
|
|
||||||
|
let precision = input.data("step") || 1; // data-step is always based on the default firmware units.
|
||||||
|
precision = self.countDecimals(precision);
|
||||||
|
|
||||||
|
if (precision === 0) {
|
||||||
|
value = Math.round(parseFloat(input.val()) * multiplier);
|
||||||
|
} else {
|
||||||
|
value = Math.round((parseFloat(input.val()) * multiplier) * Math.pow(10, precision)) / Math.pow(10, precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value > parseInt(input.data('default-max'))) {
|
||||||
|
value = parseInt(input.data('default-max'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < parseInt(input.data('default-min'))) {
|
||||||
|
value = parseInt(input.data('default-min'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mspHelper.setSetting(settingName, value);
|
return mspHelper.setSetting(settingName, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.countDecimals = function(value) {
|
||||||
|
let text = value.toString()
|
||||||
|
// verify if number 0.000005 is represented as "5e-6"
|
||||||
|
if (text.indexOf('e-') > -1) {
|
||||||
|
let [base, trail] = text.split('e-');
|
||||||
|
let deg = parseInt(trail, 10);
|
||||||
|
return deg;
|
||||||
|
}
|
||||||
|
// count decimals for number in representation like "0.123456"
|
||||||
|
if (Math.floor(value) !== value) {
|
||||||
|
return value.toString().split(".")[1].length || 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
self.saveInputs = function() {
|
self.saveInputs = function() {
|
||||||
var inputs = [];
|
var inputs = [];
|
||||||
$('[data-setting!=""][data-setting]').each(function() {
|
$('[data-setting!=""][data-setting]').each(function() {
|
||||||
|
@ -533,7 +613,7 @@ var Settings = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof dataSettingName !== "undefined" && dataSettingName !== "") {
|
if (typeof dataSettingName !== "undefined" && dataSettingName !== "") {
|
||||||
helpIcon.wrap('<a class="helpiconLink" href="https://github.com/iNavFlight/inav/blob/master/docs/Settings.md#' + dataSettingName + '" target="_blank"></a>');
|
helpIcon.wrap('<a class="helpiconLink" href="' + globalSettings.docsTreeLocation + 'Settings.md#' + dataSettingName + '" target="_blank"></a>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
270
js/sitl.js
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const { spawn } = require('node:child_process');
|
||||||
|
const pathMod = require('path');
|
||||||
|
const { chmod, rm } = require('node:fs');
|
||||||
|
|
||||||
|
const serialRXProtocolls = [
|
||||||
|
{
|
||||||
|
name : "SBus",
|
||||||
|
baudrate: 100000,
|
||||||
|
stopBits: "Two",
|
||||||
|
parity: "Even"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : "SBus Fast",
|
||||||
|
baudrate: 200000,
|
||||||
|
stopBits: "Two",
|
||||||
|
parity: "Even"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : "Crossfire/Ghost",
|
||||||
|
baudrate: 420000,
|
||||||
|
stopBits: "One",
|
||||||
|
parity: "None"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : "FPort/IBus/Spektrum/SRXL2/SUMD",
|
||||||
|
baudrate: 115200,
|
||||||
|
stopBits: "One",
|
||||||
|
parity: "None"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : "JETI EX Bus",
|
||||||
|
baudrate: 125000,
|
||||||
|
stopBits: "One",
|
||||||
|
parity: "None"
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
var Ser2TCP = {
|
||||||
|
|
||||||
|
isRunning: false,
|
||||||
|
process: null,
|
||||||
|
portsList: [],
|
||||||
|
stopPolling: false,
|
||||||
|
|
||||||
|
getProtocolls: function() {
|
||||||
|
return serialRXProtocolls;
|
||||||
|
},
|
||||||
|
|
||||||
|
start: function(comPort, serialPortOptions, ipAddress, tcpPort, callback) {
|
||||||
|
|
||||||
|
if (this.isRunning)
|
||||||
|
this.stop();
|
||||||
|
|
||||||
|
var path;
|
||||||
|
if (GUI.operating_system == 'Windows') {
|
||||||
|
path = './resources/sitl/windows/Ser2TCP.exe'
|
||||||
|
} else if (GUI.operating_system == 'Linux') {
|
||||||
|
path = './resources/sitl/linux/Ser2TCP'
|
||||||
|
chmod(path, 0o755, (err) => {
|
||||||
|
if (err)
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var protocoll = serialRXProtocolls.find(proto => {
|
||||||
|
return proto.name == serialPortOptions.protocollName;
|
||||||
|
});
|
||||||
|
|
||||||
|
var args = [];
|
||||||
|
if (protocoll && protocoll.name != "manual") {
|
||||||
|
args.push(`--comport=${comPort}`)
|
||||||
|
args.push(`--baudrate=${protocoll.baudrate}`);
|
||||||
|
args.push(`--stopbits=${protocoll.stopBits}`)
|
||||||
|
args.push(`--parity=${protocoll.parity}`)
|
||||||
|
args.push(`--ip=${ipAddress}`);
|
||||||
|
args.push(`--tcpport=${tcpPort}`);
|
||||||
|
} else {
|
||||||
|
args.push(`--comport=${comPort}`)
|
||||||
|
args.push(`--baudrate${proserialPortOptionstocoll.baudrate}`);
|
||||||
|
args.push(`--stopbits=${protserialPortOptionsocoll.stopBits}`)
|
||||||
|
args.push(`--parity=${serialPortOptions.parity}`)
|
||||||
|
args.push(`--ip=${ipAddress}`);
|
||||||
|
args.push(`--tcpport=${tcpPort}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
var opts = undefined;
|
||||||
|
if (GUI.operating_system == 'Linux')
|
||||||
|
opts = { useShell: true };
|
||||||
|
|
||||||
|
this.process = spawn(path, args, opts);
|
||||||
|
this.isRunning = true;
|
||||||
|
|
||||||
|
this.process.stdout.on('data', (data) => {
|
||||||
|
if (callback)
|
||||||
|
callback(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.process.stderr.on('data', (data) => {
|
||||||
|
if (callback)
|
||||||
|
callback(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.process.on('error', (error) => {
|
||||||
|
if (callback)
|
||||||
|
callback(error);
|
||||||
|
this.isRunning = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.process.on('exit', () => {
|
||||||
|
if (this.isRunning)
|
||||||
|
this.spawn(path, args, callback);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
stop: function() {
|
||||||
|
if (this.isRunning) {
|
||||||
|
this.isRunning = false;
|
||||||
|
this.process.kill();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getDevices: function(callback) {
|
||||||
|
chrome.serial.getDevices((devices_array) => {
|
||||||
|
var devices = [];
|
||||||
|
devices_array.forEach((device) => {
|
||||||
|
|
||||||
|
if (GUI.operating_system == 'Windows') {
|
||||||
|
var m = device.path.match(/COM\d?\d/g)
|
||||||
|
if (m)
|
||||||
|
devices.push(m[0]);
|
||||||
|
} else {
|
||||||
|
if (device.displayName != null) {
|
||||||
|
var m = device.path.match(/\/dev\/.*/)
|
||||||
|
if (m)
|
||||||
|
devices.push(m[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
callback(devices);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
pollSerialPorts: function(callback) {
|
||||||
|
this.getDevices(devices => {
|
||||||
|
if (!this.arraysEqual(this.portsList, devices)) {
|
||||||
|
this.portsList = devices;
|
||||||
|
if (callback)
|
||||||
|
callback(this.portsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
if (!this.stopPolling) {
|
||||||
|
setTimeout(() => { this.pollSerialPorts(callback) }, 250);
|
||||||
|
} else {
|
||||||
|
this.stopPolling = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
resetPortsList: function() {
|
||||||
|
this.portsList = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
stopPollSerialPorts: function()
|
||||||
|
{
|
||||||
|
this.stopPolling = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
arraysEqual: function(a, b) {
|
||||||
|
if (a === b) return true;
|
||||||
|
if (a == null || b == null) return false;
|
||||||
|
if (a.length !== b.length) return false;
|
||||||
|
|
||||||
|
for (var i = 0; i < a.length; ++i) {
|
||||||
|
if (a[i] !== b[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var SITLProcess = {
|
||||||
|
|
||||||
|
spawn : null,
|
||||||
|
isRunning: false,
|
||||||
|
process: null,
|
||||||
|
|
||||||
|
deleteEepromFile(filename) {
|
||||||
|
rm(`${nw.App.dataPath}/${filename}`, error => {
|
||||||
|
if (error) {
|
||||||
|
GUI.log(`Unable to reset Demo mode: ${error.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
start: function(eepromFileName, sim, useIMU, simIp, simPort, channelMap, callback) {
|
||||||
|
|
||||||
|
if (this.isRunning)
|
||||||
|
this.stop();
|
||||||
|
|
||||||
|
var sitlExePath, eepromPath;
|
||||||
|
if (GUI.operating_system == 'Windows') {
|
||||||
|
sitlExePath = './resources/sitl/windows/inav_SITL.exe'
|
||||||
|
eepromPath = `${nw.App.dataPath}\\${eepromFileName}`
|
||||||
|
} else if (GUI.operating_system == 'Linux') {
|
||||||
|
sitlExePath = './resources/sitl/linux/inav_SITL';
|
||||||
|
eepromPath = `${nw.App.dataPath}/${eepromFileName}`
|
||||||
|
chmod(sitlExePath, 0o755, err => {
|
||||||
|
if (err)
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var args = [];
|
||||||
|
args.push(`--path=${eepromPath}`);
|
||||||
|
|
||||||
|
if (sim) {
|
||||||
|
args.push(`--sim=${sim}`);
|
||||||
|
if (useIMU)
|
||||||
|
args.push("--useimu")
|
||||||
|
|
||||||
|
if (simIp)
|
||||||
|
args.push(`--simip=${simIp}`);
|
||||||
|
|
||||||
|
if (simPort)
|
||||||
|
args.push(`--simport=${simPort}`);
|
||||||
|
|
||||||
|
if (channelMap)
|
||||||
|
args.push(`--chanmap=${channelMap}`)
|
||||||
|
}
|
||||||
|
this.spawn(sitlExePath, args, callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
spawn: function(path, args, callback) {
|
||||||
|
|
||||||
|
var opts = undefined;
|
||||||
|
if (GUI.operating_system == 'Linux')
|
||||||
|
opts = { useShell: true };
|
||||||
|
|
||||||
|
this.process = spawn(path, args, opts);
|
||||||
|
this.isRunning = true;
|
||||||
|
|
||||||
|
this.process.stdout.on('data', (data) => {
|
||||||
|
if (callback)
|
||||||
|
callback(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.process.stderr.on('data', (data) => {
|
||||||
|
if (callback)
|
||||||
|
callback(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.process.on('error', (error) => {
|
||||||
|
if (callback)
|
||||||
|
callback(error);
|
||||||
|
this.isRunning = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
stop: function() {
|
||||||
|
if (this.isRunning) {
|
||||||
|
this.isRunning = false;
|
||||||
|
this.process.kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -139,7 +139,7 @@ let Waypoint = function (number, action, lat, lon, alt=0, p1=0, p2=0, p3=0, endM
|
||||||
self.getElevation = async function (globalSettings) {
|
self.getElevation = async function (globalSettings) {
|
||||||
let elevation = "N/A";
|
let elevation = "N/A";
|
||||||
if (globalSettings.mapProviderType == 'bing') {
|
if (globalSettings.mapProviderType == 'bing') {
|
||||||
let elevationEarthModel = $('#elevationEarthModel').prop("checked") ? "sealevel" : "ellipsoid";
|
let elevationEarthModel = $('#elevationEarthModel').prop("checked") ? "ellipsoid" : "sealevel";
|
||||||
|
|
||||||
const response = await fetch('http://dev.virtualearth.net/REST/v1/Elevation/List?points='+self.getLatMap()+','+self.getLonMap()+'&heights='+elevationEarthModel+'&key='+globalSettings.mapApiKey);
|
const response = await fetch('http://dev.virtualearth.net/REST/v1/Elevation/List?points='+self.getLatMap()+','+self.getLonMap()+'&heights='+elevationEarthModel+'&key='+globalSettings.mapApiKey);
|
||||||
const myJson = await response.json();
|
const myJson = await response.json();
|
||||||
|
|
|
@ -360,7 +360,8 @@ let WaypointCollection = function () {
|
||||||
}
|
}
|
||||||
altPoint2measure.push(self.getWaypoint(nStart).getAlt());
|
altPoint2measure.push(self.getWaypoint(nStart).getAlt());
|
||||||
namePoint2measure.push(self.getWaypoint(nStart).getLayerNumber()+1);
|
namePoint2measure.push(self.getWaypoint(nStart).getLayerNumber()+1);
|
||||||
refPoint2measure.push(self.getWaypoint(nStart).getP3());
|
let useAbsoluteAlt = (self.getWaypoint(nStart).getP3() & (1 << 0));
|
||||||
|
refPoint2measure.push(useAbsoluteAlt);
|
||||||
nStart++;
|
nStart++;
|
||||||
}
|
}
|
||||||
else if (self.getWaypoint(nStart).getAction() == MWNP.WPTYPE.JUMP) {
|
else if (self.getWaypoint(nStart).getAction() == MWNP.WPTYPE.JUMP) {
|
||||||
|
|
62
main.css
|
@ -60,6 +60,10 @@ a.disabled {
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inputRequiredWarning {
|
||||||
|
border: 3px solid #d40000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.cf_doc_version_bt a {
|
.cf_doc_version_bt a {
|
||||||
padding: 1px 9px 1px 9px;
|
padding: 1px 9px 1px 9px;
|
||||||
margin-top: -45px;
|
margin-top: -45px;
|
||||||
|
@ -322,27 +326,6 @@ input[type="number"]::-webkit-inner-spin-button {
|
||||||
color: #d40000;
|
color: #d40000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.imu2icon {
|
|
||||||
background: url("../images/icons/sensor_imu2_off.png") no-repeat -5px 2px;
|
|
||||||
background-size: 40px;
|
|
||||||
height: 30px;
|
|
||||||
margin-top: 3px;
|
|
||||||
width: 100%;
|
|
||||||
padding-top: 40px;
|
|
||||||
color: #4f4f4f;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.imu2icon.active {
|
|
||||||
background-image: url("../images/icons/sensor_imu2_on.png");
|
|
||||||
color: #818181;
|
|
||||||
}
|
|
||||||
|
|
||||||
.imu2icon.error {
|
|
||||||
background-image: url("../images/icons/sensor_imu2_error.png");
|
|
||||||
color: #d40000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.magicon {
|
.magicon {
|
||||||
background: url("../images/icons/sensor_mag_off.png") no-repeat -5px 2px;
|
background: url("../images/icons/sensor_mag_off.png") no-repeat -5px 2px;
|
||||||
background-size: 42px;
|
background-size: 42px;
|
||||||
|
@ -906,6 +889,18 @@ li.active .ic_flasher {
|
||||||
background-image: url("../images/icons/cf_icon_flasher_white.svg");
|
background-image: url("../images/icons/cf_icon_flasher_white.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ic_sitl {
|
||||||
|
background-image: url("../images/icons/cf_icon_sitl_grey.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.ic_sitl:hover {
|
||||||
|
background-image: url("../images/icons/cf_icon_sitl_white.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
li.active .ic_sitl {
|
||||||
|
background-image: url("../images/icons/cf_icon_sitl_white.svg");
|
||||||
|
}
|
||||||
|
|
||||||
.ic_calibration {
|
.ic_calibration {
|
||||||
background-image: url(../images/icons/cf_icon_cal_grey.svg);
|
background-image: url(../images/icons/cf_icon_cal_grey.svg);
|
||||||
}
|
}
|
||||||
|
@ -1648,7 +1643,7 @@ dialog {
|
||||||
/* fixing padding for all Tabs*/
|
/* fixing padding for all Tabs*/
|
||||||
.tab-setup, .tab-landing, .tab-adjustments, .tab-auxiliary, .tab-cli, .tab-configuration, .tab-failsafe, .tab-onboard_logging,
|
.tab-setup, .tab-landing, .tab-adjustments, .tab-auxiliary, .tab-cli, .tab-configuration, .tab-failsafe, .tab-onboard_logging,
|
||||||
.tab-firmware_flasher, .tab-gps, .tab-magnetometer, .tab-help, .tab-led-strip, .tab-logging, .tab-modes, .tab-motors, .tab-pid_tuning,
|
.tab-firmware_flasher, .tab-gps, .tab-magnetometer, .tab-help, .tab-led-strip, .tab-logging, .tab-modes, .tab-motors, .tab-pid_tuning,
|
||||||
.tab-ports, .tab-receiver, .tab-sensors, .tab-servos, .tab-osd, .tab-calibration {
|
.tab-ports, .tab-receiver, .tab-sensors, .tab-servos, .tab-osd, .tab-calibration, .tab-ez_tune {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
@ -1690,7 +1685,7 @@ dialog {
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
width: 269px;
|
width: 410px;
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
line-height: 12px;
|
line-height: 12px;
|
||||||
|
@ -1705,6 +1700,15 @@ dialog {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#mixer_profile_change {
|
||||||
|
color: white;
|
||||||
|
margin-top: 16px;
|
||||||
|
width: 130px;
|
||||||
|
float: left;
|
||||||
|
margin-right: 10px;
|
||||||
|
line-height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
#profile_change {
|
#profile_change {
|
||||||
color: white;
|
color: white;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
@ -2010,6 +2014,10 @@ select {
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lc_disabled {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
.ic_osd {
|
.ic_osd {
|
||||||
background-image: url("../images/icons/icon_osd.svg");
|
background-image: url("../images/icons/icon_osd.svg");
|
||||||
background-position-y: 4px;
|
background-position-y: 4px;
|
||||||
|
@ -2276,3 +2284,11 @@ ol li {
|
||||||
.controlProfileHighlightActive {
|
.controlProfileHighlightActive {
|
||||||
background-color: #d5ebfe !important ;
|
background-color: #d5ebfe !important ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-border {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
91
main.html
|
@ -27,11 +27,11 @@
|
||||||
<div class="headerbar">
|
<div class="headerbar">
|
||||||
<div id="logo">
|
<div id="logo">
|
||||||
<div class="logo_text">
|
<div class="logo_text">
|
||||||
CONFIGURATOR
|
<span i18n="mainLogoText"></span>
|
||||||
<div class="version"></div>
|
<div class="version"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="logo_text_firmware">
|
<div class="logo_text_firmware">
|
||||||
FC FIRMWARE
|
<span i18n="mainLogoTextFirmware"></span>
|
||||||
<div class="firmware_version"></div>
|
<div class="firmware_version"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,15 +46,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="portsinput">
|
<div id="portsinput">
|
||||||
<div class="portsinput__row">
|
<div class="portsinput__row">
|
||||||
<div id="port-override-option"
|
<div id="port-override-option" class="portsinput__top-element portsinput__top-element--port-override">
|
||||||
class="portsinput__top-element portsinput__top-element--port-override">
|
<label id="port-override-label" for="port-override" i18n="mainPortOverrideLabel"></label>
|
||||||
<label id="port-override-label" for="port-override">Port: </label>
|
|
||||||
<input id="port-override" type="text" value="/dev/rfcomm0" />
|
<input id="port-override" type="text" value="/dev/rfcomm0" />
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown dropdown-dark portsinput__top-element">
|
<div class="dropdown dropdown-dark portsinput__top-element">
|
||||||
<!--suppress HtmlFormInputWithoutLabel -->
|
<!--suppress HtmlFormInputWithoutLabel -->
|
||||||
<select class="dropdown-select" id="port" title="Port">
|
<select class="dropdown-select" id="port" title="Port">
|
||||||
<option value="manual">Manual</option>
|
<option value="manual" i18n="mainManual"></option>
|
||||||
<!-- port list gets generated here -->
|
<!-- port list gets generated here -->
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -86,20 +85,30 @@
|
||||||
</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="mixer_profile_change">
|
||||||
|
<div class="dropdown dropdown-dark">
|
||||||
|
<form name="mixer-profile-change" id="mixer-profile-change">
|
||||||
|
<select class="dropdown-select" id="mixerprofilechange">
|
||||||
|
<option value="0" i18n="mixerProfile1"></option>
|
||||||
|
<option value="1" i18n="mixerProfile2"></option>
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="profile_change">
|
<div id="profile_change">
|
||||||
<div class="dropdown dropdown-dark">
|
<div class="dropdown dropdown-dark">
|
||||||
<form name="profile-change" id="profile-change">
|
<form name="profile-change" id="profile-change">
|
||||||
<!--suppress HtmlFormInputWithoutLabel -->
|
<!--suppress HtmlFormInputWithoutLabel -->
|
||||||
<select class="dropdown-select" id="profilechange">
|
<select class="dropdown-select" id="profilechange">
|
||||||
<option value="0">Profile 1</option>
|
<option value="0" i18n="sensorProfile1"></option>
|
||||||
<option value="1">Profile 2</option>
|
<option value="1" i18n="sensorProfile2"></option>
|
||||||
<option value="2">Profile 3</option>
|
<option value="2" i18n="sensorProfile3"></option>
|
||||||
</select>
|
</select>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -109,9 +118,9 @@
|
||||||
<form name="battery-profile-change" id="battery-profile-change">
|
<form name="battery-profile-change" id="battery-profile-change">
|
||||||
<!--suppress HtmlFormInputWithoutLabel -->
|
<!--suppress HtmlFormInputWithoutLabel -->
|
||||||
<select class="dropdown-select" id="batteryprofilechange">
|
<select class="dropdown-select" id="batteryprofilechange">
|
||||||
<option value="0">Battery profile 1</option>
|
<option value="0" i18n="sensorBatteryProfile1"></option>
|
||||||
<option value="1">Battery profile 2</option>
|
<option value="1" i18n="sensorBatteryProfile2"></option>
|
||||||
<option value="2">Battery profile 3</option>
|
<option value="2" i18n="sensorBatteryProfile3"></option>
|
||||||
</select>
|
</select>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -119,32 +128,30 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="sensor-status" class="sensor_state mode-connected">
|
<div id="sensor-status" class="sensor_state mode-connected">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="gyro" title="Gyroscope">
|
<li class="gyro" i18n_title="sensorStatusGyro">
|
||||||
<div class="gyroicon">Gyro</div>
|
<div class="gyroicon" i18n="sensorStatusGyroShort"></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="accel" title="Accelerometer">
|
<li class="accel" i18n_title="sensorStatusAccel">
|
||||||
<div class="accicon">Accel</div>
|
<div class="accicon" i18n="sensorStatusAccelShort"></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="mag" title="Magnetometer">
|
<li class="mag" i18n_title="sensorStatusMag">
|
||||||
<div class="magicon">Mag</div>
|
<div class="magicon" i18n="sensorStatusMagShort"></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="baro" title="Barometer">
|
<li class="baro" i18n_title="sensorStatusBaro">
|
||||||
<div class="baroicon">Baro</div>
|
<div class="baroicon" i18n="sensorStatusBaroShort"></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="gps" title="GPS">
|
<li class="gps" i18n_title="sensorStatusGPS">
|
||||||
<div class="gpsicon">GPS</div>
|
<div class="gpsicon" i18n="sensorStatusGPSShort"></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="opflow" title="Optical flow">
|
|
||||||
<div class="opflowicon">Flow</div>
|
<li class="opflow" i18n_title="sensorOpticalFlow">
|
||||||
|
<div class="opflowicon" i18n="sensorOpticalFlowShort"></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="sonar" title="Sonar / Range finder">
|
<li class="sonar" i18n_title="sensorStatusSonar">
|
||||||
<div class="sonaricon">Sonar</div>
|
<div class="sonaricon" i18n="sensorStatusSonarShort"></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="airspeed" title="Airspeed">
|
<li class="airspeed" i18n_title="sensorAirspeed">
|
||||||
<div class="airspeedicon">Speed</div>
|
<div class="airspeedicon" i18n="sensorAirspeedShort"></div>
|
||||||
</li>
|
|
||||||
<li class="imu2" title="IMU2">
|
|
||||||
<div class="imu2icon">IMU2</div>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -154,7 +161,7 @@
|
||||||
<div class="battery-status"></div>
|
<div class="battery-status"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="battery-legend">Battery voltage</div>
|
<div class="battery-legend" i18n="sensorBatteryVoltage"></div>
|
||||||
<div class="bottomStatusIcons">
|
<div class="bottomStatusIcons">
|
||||||
<div class="armedicon cf_tip" data-i18n_title="mainHelpArmed"></div>
|
<div class="armedicon cf_tip" data-i18n_title="mainHelpArmed"></div>
|
||||||
<div class="failsafeicon cf_tip" data-i18n_title="mainHelpFailsafe"></div>
|
<div class="failsafeicon cf_tip" data-i18n_title="mainHelpFailsafe"></div>
|
||||||
|
@ -166,7 +173,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="mainShowLog"></a>
|
||||||
</div>
|
</div>
|
||||||
<div id="scrollicon"></div>
|
<div id="scrollicon"></div>
|
||||||
<div class="wrapper"></div>
|
<div class="wrapper"></div>
|
||||||
|
@ -189,6 +196,9 @@
|
||||||
<a href="#" data-i18n="tabFirmwareFlasher" class="tabicon ic_flasher"
|
<a href="#" data-i18n="tabFirmwareFlasher" class="tabicon ic_flasher"
|
||||||
title="Firmware Flasher"></a>
|
title="Firmware Flasher"></a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="tab_sitl">
|
||||||
|
<a href="#" data-i18n="tabSitl" class="tabicon ic_sitl" title="SITL"></a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="mode-connected">
|
<ul class="mode-connected">
|
||||||
<li class="tab_setup">
|
<li class="tab_setup">
|
||||||
|
@ -212,6 +222,9 @@
|
||||||
<li class="tab_failsafe">
|
<li class="tab_failsafe">
|
||||||
<a href="#" data-i18n="tabFailsafe" class="tabicon ic_failsafe" title="Failsafe"></a>
|
<a href="#" data-i18n="tabFailsafe" class="tabicon ic_failsafe" title="Failsafe"></a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="tab_ez_tune">
|
||||||
|
<a href="#" data-i18n="tabEzTune" class="tabicon ic_wizzard"></a>
|
||||||
|
</li>
|
||||||
<li class="tab_pid_tuning">
|
<li class="tab_pid_tuning">
|
||||||
<a href="#" data-i18n="tabPidTuning" class="tabicon ic_pid" title="PID Tuning"></a>
|
<a href="#" data-i18n="tabPidTuning" class="tabicon ic_pid" title="PID Tuning"></a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -260,8 +273,7 @@
|
||||||
<a href="#" data-i18n="tabCLI" class="tabicon ic_cli" title="CLI"></a>
|
<a href="#" data-i18n="tabCLI" class="tabicon ic_cli" title="CLI"></a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!--<li class=""><a href="#" class="tabicon ic_advanced">Advanced (spare icon)</a></li>-->
|
<!-- <li class=""><a href="#" class="tabicon ic_advanced">Advanced (spare icon)</a></li> -->
|
||||||
<!--<li class=""><a href="#" class="tabicon ic_wizzard">Wizzard (spare icon)</a></li>-->
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear-both"></div>
|
<div class="clear-both"></div>
|
||||||
|
@ -295,13 +307,16 @@
|
||||||
<div>
|
<div>
|
||||||
<span id="drop-rate"> </span>
|
<span id="drop-rate"> </span>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<span data-i18n="statusbar_arming_flags"></span> <span class="arming-flags">-</span>
|
||||||
|
</div>
|
||||||
<div class="version">
|
<div class="version">
|
||||||
<!-- configuration version generated here -->
|
<!-- configuration version generated here -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="cache">
|
<div id="cache">
|
||||||
<div class="data-loading">
|
<div class="data-loading">
|
||||||
<p>Waiting for data ...</p>
|
<p i18n="waitingForData"></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
122
main.js
|
@ -24,12 +24,16 @@ let globalSettings = {
|
||||||
// Used to depict how the units are displayed within the UI
|
// Used to depict how the units are displayed within the UI
|
||||||
unitType: null,
|
unitType: null,
|
||||||
// Used to convert units within the UI
|
// Used to convert units within the UI
|
||||||
osdUnits: null,
|
osdUnits: null,
|
||||||
|
// Map
|
||||||
mapProviderType: null,
|
mapProviderType: null,
|
||||||
mapApiKey: null,
|
mapApiKey: null,
|
||||||
proxyURL: null,
|
proxyURL: null,
|
||||||
proxyLayer: null,
|
proxyLayer: null,
|
||||||
|
// Show colours for profiles
|
||||||
showProfileParameters: null,
|
showProfileParameters: null,
|
||||||
|
// tree target for documents
|
||||||
|
docsTreeLocation: 'master',
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
@ -74,6 +78,14 @@ $(document).ready(function () {
|
||||||
// Update CSS on to show highlighing or not
|
// Update CSS on to show highlighing or not
|
||||||
updateProfilesHighlightColours();
|
updateProfilesHighlightColours();
|
||||||
});
|
});
|
||||||
|
chrome.storage.local.get('cli_autocomplete', function (result) {
|
||||||
|
if (typeof result.cliAutocomplete === 'undefined') {
|
||||||
|
result.cli_autocomplete = 1;
|
||||||
|
}
|
||||||
|
globalSettings.cliAutocomplete = result.cli_autocomplete;
|
||||||
|
CliAutoComplete.setEnabled(globalSettings.cliAutocomplete);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Resets the OSD units used by the unit coversion when the FC is disconnected.
|
// Resets the OSD units used by the unit coversion when the FC is disconnected.
|
||||||
if (!CONFIGURATOR.connectionValid) {
|
if (!CONFIGURATOR.connectionValid) {
|
||||||
|
@ -81,9 +93,9 @@ $(document).ready(function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// alternative - window.navigator.appVersion.match(/Chrome\/([0-9.]*)/)[1];
|
// alternative - window.navigator.appVersion.match(/Chrome\/([0-9.]*)/)[1];
|
||||||
GUI.log('Running - OS: <strong>' + GUI.operating_system + '</strong>, ' +
|
GUI.log(chrome.i18n.getMessage('getRunningOS') + GUI.operating_system + '</strong>, ' +
|
||||||
'Chrome: <strong>' + window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/, "$1") + '</strong>, ' +
|
'Chrome: <strong>' + window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/, "$1") + '</strong>, ' +
|
||||||
'Configurator: <strong>' + chrome.runtime.getManifest().version + '</strong>');
|
chrome.i18n.getMessage('getConfiguratorVersion') + chrome.runtime.getManifest().version + '</strong>');
|
||||||
|
|
||||||
$('#status-bar .version').text(chrome.runtime.getManifest().version);
|
$('#status-bar .version').text(chrome.runtime.getManifest().version);
|
||||||
$('#logo .version').text(chrome.runtime.getManifest().version);
|
$('#logo .version').text(chrome.runtime.getManifest().version);
|
||||||
|
@ -118,10 +130,14 @@ $(document).ready(function () {
|
||||||
//Get saved size and position
|
//Get saved size and position
|
||||||
chrome.storage.local.get('windowSize', function (result) {
|
chrome.storage.local.get('windowSize', function (result) {
|
||||||
if (result.windowSize) {
|
if (result.windowSize) {
|
||||||
win.height = result.windowSize.height;
|
if (result.windowSize.height <= window.screen.availHeight)
|
||||||
win.width = result.windowSize.width;
|
win.height = result.windowSize.height;
|
||||||
win.x = result.windowSize.x;
|
if (result.windowSize.width <= window.screen.availWidth)
|
||||||
win.y = result.windowSize.y;
|
win.width = result.windowSize.width;
|
||||||
|
if (result.windowSize.x >= window.screen.availLeft)
|
||||||
|
win.x = result.windowSize.x;
|
||||||
|
if (result.windowSize.y >= window.screen.availTop)
|
||||||
|
win.y = result.windowSize.y;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -219,6 +235,9 @@ $(document).ready(function () {
|
||||||
case 'firmware_flasher':
|
case 'firmware_flasher':
|
||||||
TABS.firmware_flasher.initialize(content_ready);
|
TABS.firmware_flasher.initialize(content_ready);
|
||||||
break;
|
break;
|
||||||
|
case 'sitl':
|
||||||
|
TABS.sitl.initialize(content_ready);
|
||||||
|
break;
|
||||||
case 'auxiliary':
|
case 'auxiliary':
|
||||||
TABS.auxiliary.initialize(content_ready);
|
TABS.auxiliary.initialize(content_ready);
|
||||||
break;
|
break;
|
||||||
|
@ -294,6 +313,9 @@ $(document).ready(function () {
|
||||||
case 'cli':
|
case 'cli':
|
||||||
TABS.cli.initialize(content_ready);
|
TABS.cli.initialize(content_ready);
|
||||||
break;
|
break;
|
||||||
|
case 'ez_tune':
|
||||||
|
TABS.ez_tune.initialize(content_ready);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.log('Tab not found:' + tab);
|
console.log('Tab not found:' + tab);
|
||||||
|
@ -357,6 +379,15 @@ $(document).ready(function () {
|
||||||
activeTab.removeClass('active');
|
activeTab.removeClass('active');
|
||||||
activeTab.find('a').click();
|
activeTab.find('a').click();
|
||||||
});
|
});
|
||||||
|
$('div.cli_autocomplete input').change(function () {
|
||||||
|
globalSettings.cliAutocomplete = $(this).is(':checked');
|
||||||
|
chrome.storage.local.set({
|
||||||
|
'cli_autocomplete': globalSettings.cliAutocomplete
|
||||||
|
});
|
||||||
|
|
||||||
|
CliAutoComplete.setEnabled($(this).is(':checked'));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
$('#ui-unit-type').val(globalSettings.unitType);
|
$('#ui-unit-type').val(globalSettings.unitType);
|
||||||
$('#map-provider-type').val(globalSettings.mapProviderType);
|
$('#map-provider-type').val(globalSettings.mapProviderType);
|
||||||
|
@ -364,6 +395,7 @@ $(document).ready(function () {
|
||||||
$('#proxyurl').val(globalSettings.proxyURL);
|
$('#proxyurl').val(globalSettings.proxyURL);
|
||||||
$('#proxylayer').val(globalSettings.proxyLayer);
|
$('#proxylayer').val(globalSettings.proxyLayer);
|
||||||
$('#showProfileParameters').prop('checked', globalSettings.showProfileParameters);
|
$('#showProfileParameters').prop('checked', globalSettings.showProfileParameters);
|
||||||
|
$('#cliAutocomplete').prop('checked', globalSettings.cliAutocomplete);
|
||||||
|
|
||||||
// Set the value of the unit type
|
// Set the value of the unit type
|
||||||
// none, OSD, imperial, metric
|
// none, OSD, imperial, metric
|
||||||
|
@ -408,6 +440,9 @@ $(document).ready(function () {
|
||||||
});
|
});
|
||||||
globalSettings.proxyLayer = $(this).val();
|
globalSettings.proxyLayer = $(this).val();
|
||||||
});
|
});
|
||||||
|
$('#demoModeReset').on('click', () => {
|
||||||
|
SITLProcess.deleteEepromFile('demo.bin');
|
||||||
|
});
|
||||||
function close_and_cleanup(e) {
|
function close_and_cleanup(e) {
|
||||||
if (e.type == 'click' && !$.contains($('div#options-window')[0], e.target) || e.type == 'keyup' && e.keyCode == 27) {
|
if (e.type == 'click' && !$.contains($('div#options-window')[0], e.target) || e.type == 'keyup' && e.keyCode == 27) {
|
||||||
$(document).unbind('click keyup', close_and_cleanup);
|
$(document).unbind('click keyup', close_and_cleanup);
|
||||||
|
@ -530,18 +565,30 @@ $(document).ready(function () {
|
||||||
|
|
||||||
state = true;
|
state = true;
|
||||||
}
|
}
|
||||||
$(this).text(state ? 'Hide Log' : 'Show Log');
|
$(this).html(state ? chrome.i18n.getMessage("mainHideLog") : chrome.i18n.getMessage("mainShowLog"));
|
||||||
$(this).data('state', state);
|
$(this).data('state', state);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var mixerprofile_e = $('#mixerprofilechange');
|
||||||
|
|
||||||
|
mixerprofile_e.change(function () {
|
||||||
|
var mixerprofile = parseInt($(this).val());
|
||||||
|
MSP.send_message(MSPCodes.MSP2_INAV_SELECT_MIXER_PROFILE, [mixerprofile], false, function () {
|
||||||
|
GUI.log(chrome.i18n.getMessage('loadedMixerProfile', [mixerprofile + 1]));
|
||||||
|
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, function () {
|
||||||
|
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||||
|
GUI.handleReconnect();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var profile_e = $('#profilechange');
|
var profile_e = $('#profilechange');
|
||||||
|
|
||||||
profile_e.change(function () {
|
profile_e.change(function () {
|
||||||
var profile = parseInt($(this).val());
|
var profile = parseInt($(this).val());
|
||||||
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [profile], false, function () {
|
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [profile], false, function () {
|
||||||
GUI.log(chrome.i18n.getMessage('pidTuning_LoadedProfile', [profile + 1]));
|
GUI.log(chrome.i18n.getMessage('pidTuning_LoadedProfile', [profile + 1]));
|
||||||
updateActivatedTab();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -551,7 +598,6 @@ $(document).ready(function () {
|
||||||
var batteryprofile = parseInt($(this).val());
|
var batteryprofile = parseInt($(this).val());
|
||||||
MSP.send_message(MSPCodes.MSP2_INAV_SELECT_BATTERY_PROFILE, [batteryprofile], false, function () {
|
MSP.send_message(MSPCodes.MSP2_INAV_SELECT_BATTERY_PROFILE, [batteryprofile], false, function () {
|
||||||
GUI.log(chrome.i18n.getMessage('loadedBatteryProfile', [batteryprofile + 1]));
|
GUI.log(chrome.i18n.getMessage('loadedBatteryProfile', [batteryprofile + 1]));
|
||||||
updateActivatedTab();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -649,6 +695,21 @@ String.prototype.format = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function padZeros(val, length) {
|
||||||
|
let str = val.toString();
|
||||||
|
|
||||||
|
if (str.length < length) {
|
||||||
|
if (str.charAt(0) === '-') {
|
||||||
|
str = "-0" + str.substring(1);
|
||||||
|
str = padZeros(str, length);
|
||||||
|
} else {
|
||||||
|
str = padZeros("0" + str, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
function updateActivatedTab() {
|
function updateActivatedTab() {
|
||||||
var activeTab = $('#tabs > ul li.active');
|
var activeTab = $('#tabs > ul li.active');
|
||||||
activeTab.removeClass('active');
|
activeTab.removeClass('active');
|
||||||
|
@ -657,8 +718,47 @@ function updateActivatedTab() {
|
||||||
|
|
||||||
function updateFirmwareVersion() {
|
function updateFirmwareVersion() {
|
||||||
if (CONFIGURATOR.connectionValid) {
|
if (CONFIGURATOR.connectionValid) {
|
||||||
$('#logo .firmware_version').text(CONFIG.flightControllerVersion);
|
$('#logo .firmware_version').text(CONFIG.flightControllerVersion + " [" + CONFIG.target + "]");
|
||||||
|
globalSettings.docsTreeLocation = 'https://github.com/iNavFlight/inav/blob/' + CONFIG.flightControllerVersion + '/docs/';
|
||||||
|
|
||||||
|
// If this is a master branch firmware, this will find a 404 as there is no tag tree. So default to master for docs.
|
||||||
|
$.ajax({
|
||||||
|
url : globalSettings.docsTreeLocation + 'Settings.md',
|
||||||
|
method: "HEAD",
|
||||||
|
statusCode: {
|
||||||
|
404: function() {
|
||||||
|
globalSettings.docsTreeLocation = 'https://github.com/iNavFlight/inav/blob/master/docs/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
$('#logo .firmware_version').text(chrome.i18n.getMessage('fcNotConnected'));
|
$('#logo .firmware_version').text(chrome.i18n.getMessage('fcNotConnected'));
|
||||||
|
|
||||||
|
globalSettings.docsTreeLocation = 'https://github.com/iNavFlight/inav/blob/master/docs/';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateEzTuneTabVisibility(loadMixerConfig) {
|
||||||
|
let useEzTune = true;
|
||||||
|
if (CONFIGURATOR.connectionValid) {
|
||||||
|
if (loadMixerConfig) {
|
||||||
|
mspHelper.loadMixerConfig(function() {
|
||||||
|
if (MIXER_CONFIG.platformType == PLATFORM_MULTIROTOR || MIXER_CONFIG.platformType == PLATFORM_TRICOPTER) {
|
||||||
|
$('.tab_ez_tune').removeClass("is-hidden");
|
||||||
|
} else {
|
||||||
|
$('.tab_ez_tune').addClass("is-hidden");
|
||||||
|
useEzTune = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (MIXER_CONFIG.platformType == PLATFORM_MULTIROTOR || MIXER_CONFIG.platformType == PLATFORM_TRICOPTER) {
|
||||||
|
$('.tab_ez_tune').removeClass("is-hidden");
|
||||||
|
} else {
|
||||||
|
$('.tab_ez_tune').addClass("is-hidden");
|
||||||
|
useEzTune = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return useEzTune;
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"minimum_chrome_version": "38",
|
"minimum_chrome_version": "38",
|
||||||
"version": "5.0.0",
|
"version": "8.0.0",
|
||||||
"author": "Several",
|
"author": "Several",
|
||||||
"name": "INAV - Configurator",
|
"name": "INAV - Configurator",
|
||||||
"short_name": "INAV",
|
"short_name": "INAV",
|
||||||
|
@ -47,7 +47,8 @@
|
||||||
"notifications",
|
"notifications",
|
||||||
"alwaysOnTopWindows",
|
"alwaysOnTopWindows",
|
||||||
{"usbDevices": [
|
{"usbDevices": [
|
||||||
{"vendorId": 1155, "productId": 57105}
|
{"vendorId": 1155, "productId": 57105},
|
||||||
|
{"vendorId": 11836, "productId": 57105}
|
||||||
]}
|
]}
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
13815
package-lock.json
generated
17
package.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "inav-configurator",
|
"name": "inav-configurator",
|
||||||
"description": "INAV Configurator",
|
"description": "INAV Configurator",
|
||||||
"version": "5.0.0",
|
"version": "8.0.0",
|
||||||
"main": "main.html",
|
"main": "main.html",
|
||||||
"default_locale": "en",
|
"default_locale": "en",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -25,17 +25,19 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"archiver": "^2.0.3",
|
"archiver": "^2.0.3",
|
||||||
"bluebird": "3.4.1",
|
"bluebird": "3.4.1",
|
||||||
|
"command-exists": "^1.2.8",
|
||||||
"del": "^3.0.0",
|
"del": "^3.0.0",
|
||||||
"fs": "0.0.1-security",
|
"fs": "0.0.1-security",
|
||||||
"graceful-fs": "^4.2.0",
|
"graceful-fs": "^4.2.0",
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"inflection": "1.12.0",
|
"inflection": "1.12.0",
|
||||||
"jquery": "2.1.4",
|
"jquery": "3.7.1",
|
||||||
|
"jquery-textcomplete": "^1.8.5",
|
||||||
"jquery-ui-npm": "1.12.0",
|
"jquery-ui-npm": "1.12.0",
|
||||||
"marked": "^0.3.17",
|
"marked": "^0.3.17",
|
||||||
"minimist": "^1.2.0",
|
"minimist": "^1.2.0",
|
||||||
"nw": "^0.61.0",
|
"nw": "^0.61.0-sdk",
|
||||||
"nw-dialog": "^1.0.7",
|
"nw-dialog": "^1.0.7",
|
||||||
"openlayers": "^4.6.5",
|
"openlayers": "^4.6.5",
|
||||||
"plotly": "^1.0.6",
|
"plotly": "^1.0.6",
|
||||||
|
@ -44,7 +46,14 @@
|
||||||
"xml2js": "^0.4.19"
|
"xml2js": "^0.4.19"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nw-builder": "^3.5.7",
|
"@quanle94/innosetup": "^6.0.2",
|
||||||
|
"gulp-debian": "^0.1.9",
|
||||||
|
"gulp-rename": "^2.0.0",
|
||||||
|
"nw-builder": "3.8.6",
|
||||||
|
"rpm-builder": "^1.2.1",
|
||||||
"semver": "6.3.0"
|
"semver": "6.3.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"appdmg": "^0.6.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
resources/adsb/adsb_1.png
Normal file
After Width: | Height: | Size: 953 B |
BIN
resources/adsb/adsb_10.png
Normal file
After Width: | Height: | Size: 962 B |
BIN
resources/adsb/adsb_11.png
Normal file
After Width: | Height: | Size: 982 B |
BIN
resources/adsb/adsb_12.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
resources/adsb/adsb_13.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/adsb/adsb_14.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/adsb/adsb_15.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
resources/adsb/adsb_2.png
Normal file
After Width: | Height: | Size: 981 B |
BIN
resources/adsb/adsb_3.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/adsb/adsb_4.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
resources/adsb/adsb_5.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
resources/adsb/adsb_6.png
Normal file
After Width: | Height: | Size: 821 B |
BIN
resources/adsb/adsb_7.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
resources/adsb/adsb_8.png
Normal file
After Width: | Height: | Size: 919 B |
BIN
resources/adsb/adsb_9.png
Normal file
After Width: | Height: | Size: 963 B |
6903
resources/models/fc.gltf
Normal file
|
@ -1,44 +1,121 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!-- Public domain (CC-BY-SA if you or your laws insist), generated by Jonathan Hudson's svg_model_motors.rb -->
|
<!-- Public domain (CC-BY-SA if you or your laws insist), generated by Jonathan Hudson's svg_model_motors.rb -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200pt" height="200pt" viewBox="0 0 200 200" version="1.1">
|
|
||||||
<defs>
|
<svg
|
||||||
<g>
|
width="200pt"
|
||||||
<symbol overflow="visible" id="glyph0-0">
|
height="200pt"
|
||||||
<path style="stroke:none;" d=""/>
|
viewBox="0 0 200 200"
|
||||||
</symbol>
|
version="1.1"
|
||||||
<symbol overflow="visible" id="glyph0-1">
|
id="svg52"
|
||||||
<path style="stroke:none;" d="M 2.679688 -13.863281 L 2.679688 -15.75 C 4.457031 -15.921875 5.695312 -16.210938 6.398438 -16.617188 C 7.101562 -17.023438 7.625 -17.984375 7.96875 -19.496094 L 9.914062 -19.496094 L 9.914062 0 L 7.289062 0 L 7.289062 -13.863281 Z M 2.679688 -13.863281 "/>
|
sodipodi:docname="quad_x.svg"
|
||||||
</symbol>
|
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||||
<symbol overflow="visible" id="glyph0-2">
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
<path style="stroke:none;" d="M 1.921875 -4.402344 C 2.527344 -5.652344 3.710938 -6.785156 5.46875 -7.804688 L 8.09375 -9.324219 C 9.269531 -10.007812 10.09375 -10.589844 10.570312 -11.074219 C 11.316406 -11.832031 11.6875 -12.695312 11.6875 -13.671875 C 11.6875 -14.8125 11.347656 -15.714844 10.664062 -16.386719 C 9.980469 -17.054688 9.070312 -17.390625 7.929688 -17.390625 C 6.242188 -17.390625 5.078125 -16.753906 4.429688 -15.476562 C 4.082031 -14.792969 3.890625 -13.84375 3.855469 -12.632812 L 1.351562 -12.632812 C 1.378906 -14.335938 1.695312 -15.726562 2.296875 -16.804688 C 3.363281 -18.699219 5.246094 -19.648438 7.945312 -19.648438 C 10.1875 -19.648438 11.824219 -19.039062 12.859375 -17.828125 C 13.894531 -16.617188 14.410156 -15.265625 14.410156 -13.78125 C 14.410156 -12.214844 13.859375 -10.875 12.757812 -9.761719 C 12.117188 -9.113281 10.972656 -8.332031 9.324219 -7.410156 L 7.453125 -6.371094 C 6.558594 -5.878906 5.855469 -5.410156 5.34375 -4.960938 C 4.433594 -4.167969 3.859375 -3.289062 3.625 -2.324219 L 14.3125 -2.324219 L 14.3125 0 L 0.875 0 C 0.964844 -1.6875 1.316406 -3.152344 1.921875 -4.402344 Z M 1.921875 -4.402344 "/>
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
</symbol>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<symbol overflow="visible" id="glyph0-3">
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
<path style="stroke:none;" d="M 2.234375 -1.375 C 1.191406 -2.644531 0.671875 -4.191406 0.671875 -6.015625 L 3.242188 -6.015625 C 3.351562 -4.75 3.585938 -3.828125 3.953125 -3.253906 C 4.589844 -2.222656 5.742188 -1.710938 7.410156 -1.710938 C 8.703125 -1.710938 9.742188 -2.054688 10.527344 -2.75 C 11.3125 -3.441406 11.703125 -4.335938 11.703125 -5.429688 C 11.703125 -6.777344 11.289062 -7.71875 10.464844 -8.257812 C 9.640625 -8.796875 8.496094 -9.0625 7.027344 -9.0625 C 6.863281 -9.0625 6.695312 -9.0625 6.527344 -9.058594 C 6.359375 -9.054688 6.1875 -9.046875 6.015625 -9.039062 L 6.015625 -11.210938 C 6.269531 -11.183594 6.484375 -11.164062 6.65625 -11.15625 C 6.832031 -11.148438 7.019531 -11.140625 7.21875 -11.140625 C 8.140625 -11.140625 8.894531 -11.289062 9.488281 -11.578125 C 10.527344 -12.089844 11.046875 -13 11.046875 -14.3125 C 11.046875 -15.289062 10.699219 -16.042969 10.007812 -16.570312 C 9.316406 -17.097656 8.507812 -17.363281 7.585938 -17.363281 C 5.945312 -17.363281 4.8125 -16.816406 4.183594 -15.722656 C 3.835938 -15.121094 3.640625 -14.265625 3.59375 -13.152344 L 1.164062 -13.152344 C 1.164062 -14.609375 1.453125 -15.851562 2.039062 -16.871094 C 3.039062 -18.695312 4.804688 -19.605469 7.328125 -19.605469 C 9.324219 -19.605469 10.867188 -19.160156 11.960938 -18.273438 C 13.054688 -17.382812 13.601562 -16.097656 13.601562 -14.410156 C 13.601562 -13.207031 13.28125 -12.230469 12.632812 -11.484375 C 12.230469 -11.019531 11.710938 -10.65625 11.074219 -10.390625 C 12.105469 -10.109375 12.910156 -9.5625 13.488281 -8.757812 C 14.066406 -7.949219 14.355469 -6.964844 14.355469 -5.796875 C 14.355469 -3.929688 13.742188 -2.40625 12.507812 -1.230469 C 11.277344 -0.0546875 9.535156 0.53125 7.273438 0.53125 C 4.957031 0.53125 3.277344 -0.101562 2.234375 -1.375 Z M 2.234375 -1.375 "/>
|
<sodipodi:namedview
|
||||||
</symbol>
|
id="namedview54"
|
||||||
<symbol overflow="visible" id="glyph0-4">
|
pagecolor="#ffffff"
|
||||||
<path style="stroke:none;" d="M 9.257812 -6.929688 L 9.257812 -15.804688 L 2.980469 -6.929688 Z M 9.296875 0 L 9.296875 -4.785156 L 0.710938 -4.785156 L 0.710938 -7.191406 L 9.679688 -19.632812 L 11.757812 -19.632812 L 11.757812 -6.929688 L 14.640625 -6.929688 L 14.640625 -4.785156 L 11.757812 -4.785156 L 11.757812 0 Z M 9.296875 0 "/>
|
bordercolor="#666666"
|
||||||
</symbol>
|
borderopacity="1.0"
|
||||||
</g>
|
inkscape:pageshadow="2"
|
||||||
</defs>
|
inkscape:pageopacity="0.0"
|
||||||
<g id="surface11">
|
inkscape:pagecheckerboard="0"
|
||||||
<path style="fill:none;stroke-width:28;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(72.941176%,72.941176%,72.941176%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40 40 L 160 160 M 40 160 L 160 40 "/>
|
inkscape:document-units="pt"
|
||||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 188 160 C 188 175.464844 175.464844 188 160 188 C 144.535156 188 132 175.464844 132 160 C 132 144.535156 144.535156 132 160 132 C 175.464844 132 188 144.535156 188 160 M 179.800781 179.800781 L 177.785156 163 M 179.800781 179.800781 L 196.601562 179.800781 "/>
|
showgrid="false"
|
||||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
inkscape:zoom="3.165"
|
||||||
<use xlink:href="#glyph0-1" x="153" y="167"/>
|
inkscape:cx="133.17536"
|
||||||
</g>
|
inkscape:cy="133.49131"
|
||||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 188 40 C 188 55.464844 175.464844 68 160 68 C 144.535156 68 132 55.464844 132 40 C 132 24.535156 144.535156 12 160 12 C 175.464844 12 188 24.535156 188 40 M 179.800781 20.199219 L 177.785156 37 M 179.800781 20.199219 L 196.601562 20.199219 "/>
|
inkscape:window-width="1850"
|
||||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
inkscape:window-height="1016"
|
||||||
<use xlink:href="#glyph0-2" x="153" y="47"/>
|
inkscape:window-x="1990"
|
||||||
</g>
|
inkscape:window-y="27"
|
||||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 68 160 C 68 175.464844 55.464844 188 40 188 C 24.535156 188 12 175.464844 12 160 C 12 144.535156 24.535156 132 40 132 C 55.464844 132 68 144.535156 68 160 M 20.199219 179.800781 L 22.214844 163 M 20.199219 179.800781 L 3.398438 179.800781 "/>
|
inkscape:window-maximized="1"
|
||||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
inkscape:current-layer="g45" />
|
||||||
<use xlink:href="#glyph0-3" x="33" y="167"/>
|
<defs
|
||||||
</g>
|
id="defs19">
|
||||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 68 40 C 68 55.464844 55.464844 68 40 68 C 24.535156 68 12 55.464844 12 40 C 12 24.535156 24.535156 12 40 12 C 55.464844 12 68 24.535156 68 40 M 20.199219 20.199219 L 22.214844 37 M 20.199219 20.199219 L 3.398438 20.199219 "/>
|
<g
|
||||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
id="g17">
|
||||||
<use xlink:href="#glyph0-4" x="33" y="47"/>
|
<symbol
|
||||||
</g>
|
overflow="visible"
|
||||||
<path style="fill:none;stroke-width:12;stroke-linecap:butt;stroke-linejoin:bevel;stroke:rgb(98.039216%,2.745098%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 100 80 L 100 120 "/>
|
id="glyph0-0">
|
||||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(98.039216%,2.745098%,0%);fill-opacity:1;" d="M 100 75 L 85 90 L 115 90 L 100 75 "/>
|
<path
|
||||||
</g>
|
style="stroke:none;"
|
||||||
|
d=""
|
||||||
|
id="path2" />
|
||||||
|
</symbol>
|
||||||
|
<symbol
|
||||||
|
overflow="visible"
|
||||||
|
id="glyph0-1">
|
||||||
|
<path
|
||||||
|
style="stroke:none;"
|
||||||
|
d="M 2.679688 -13.863281 L 2.679688 -15.75 C 4.457031 -15.921875 5.695312 -16.210938 6.398438 -16.617188 C 7.101562 -17.023438 7.625 -17.984375 7.96875 -19.496094 L 9.914062 -19.496094 L 9.914062 0 L 7.289062 0 L 7.289062 -13.863281 Z M 2.679688 -13.863281 "
|
||||||
|
id="path5" />
|
||||||
|
</symbol>
|
||||||
|
<symbol
|
||||||
|
overflow="visible"
|
||||||
|
id="glyph0-2">
|
||||||
|
<path
|
||||||
|
style="stroke:none;"
|
||||||
|
d="M 1.921875 -4.402344 C 2.527344 -5.652344 3.710938 -6.785156 5.46875 -7.804688 L 8.09375 -9.324219 C 9.269531 -10.007812 10.09375 -10.589844 10.570312 -11.074219 C 11.316406 -11.832031 11.6875 -12.695312 11.6875 -13.671875 C 11.6875 -14.8125 11.347656 -15.714844 10.664062 -16.386719 C 9.980469 -17.054688 9.070312 -17.390625 7.929688 -17.390625 C 6.242188 -17.390625 5.078125 -16.753906 4.429688 -15.476562 C 4.082031 -14.792969 3.890625 -13.84375 3.855469 -12.632812 L 1.351562 -12.632812 C 1.378906 -14.335938 1.695312 -15.726562 2.296875 -16.804688 C 3.363281 -18.699219 5.246094 -19.648438 7.945312 -19.648438 C 10.1875 -19.648438 11.824219 -19.039062 12.859375 -17.828125 C 13.894531 -16.617188 14.410156 -15.265625 14.410156 -13.78125 C 14.410156 -12.214844 13.859375 -10.875 12.757812 -9.761719 C 12.117188 -9.113281 10.972656 -8.332031 9.324219 -7.410156 L 7.453125 -6.371094 C 6.558594 -5.878906 5.855469 -5.410156 5.34375 -4.960938 C 4.433594 -4.167969 3.859375 -3.289062 3.625 -2.324219 L 14.3125 -2.324219 L 14.3125 0 L 0.875 0 C 0.964844 -1.6875 1.316406 -3.152344 1.921875 -4.402344 Z M 1.921875 -4.402344 "
|
||||||
|
id="path8" />
|
||||||
|
</symbol>
|
||||||
|
<symbol
|
||||||
|
overflow="visible"
|
||||||
|
id="glyph0-3">
|
||||||
|
<path
|
||||||
|
style="stroke:none;"
|
||||||
|
d="M 2.234375 -1.375 C 1.191406 -2.644531 0.671875 -4.191406 0.671875 -6.015625 L 3.242188 -6.015625 C 3.351562 -4.75 3.585938 -3.828125 3.953125 -3.253906 C 4.589844 -2.222656 5.742188 -1.710938 7.410156 -1.710938 C 8.703125 -1.710938 9.742188 -2.054688 10.527344 -2.75 C 11.3125 -3.441406 11.703125 -4.335938 11.703125 -5.429688 C 11.703125 -6.777344 11.289062 -7.71875 10.464844 -8.257812 C 9.640625 -8.796875 8.496094 -9.0625 7.027344 -9.0625 C 6.863281 -9.0625 6.695312 -9.0625 6.527344 -9.058594 C 6.359375 -9.054688 6.1875 -9.046875 6.015625 -9.039062 L 6.015625 -11.210938 C 6.269531 -11.183594 6.484375 -11.164062 6.65625 -11.15625 C 6.832031 -11.148438 7.019531 -11.140625 7.21875 -11.140625 C 8.140625 -11.140625 8.894531 -11.289062 9.488281 -11.578125 C 10.527344 -12.089844 11.046875 -13 11.046875 -14.3125 C 11.046875 -15.289062 10.699219 -16.042969 10.007812 -16.570312 C 9.316406 -17.097656 8.507812 -17.363281 7.585938 -17.363281 C 5.945312 -17.363281 4.8125 -16.816406 4.183594 -15.722656 C 3.835938 -15.121094 3.640625 -14.265625 3.59375 -13.152344 L 1.164062 -13.152344 C 1.164062 -14.609375 1.453125 -15.851562 2.039062 -16.871094 C 3.039062 -18.695312 4.804688 -19.605469 7.328125 -19.605469 C 9.324219 -19.605469 10.867188 -19.160156 11.960938 -18.273438 C 13.054688 -17.382812 13.601562 -16.097656 13.601562 -14.410156 C 13.601562 -13.207031 13.28125 -12.230469 12.632812 -11.484375 C 12.230469 -11.019531 11.710938 -10.65625 11.074219 -10.390625 C 12.105469 -10.109375 12.910156 -9.5625 13.488281 -8.757812 C 14.066406 -7.949219 14.355469 -6.964844 14.355469 -5.796875 C 14.355469 -3.929688 13.742188 -2.40625 12.507812 -1.230469 C 11.277344 -0.0546875 9.535156 0.53125 7.273438 0.53125 C 4.957031 0.53125 3.277344 -0.101562 2.234375 -1.375 Z M 2.234375 -1.375 "
|
||||||
|
id="path11" />
|
||||||
|
</symbol>
|
||||||
|
<symbol
|
||||||
|
overflow="visible"
|
||||||
|
id="glyph0-4">
|
||||||
|
<path
|
||||||
|
style="stroke:none;"
|
||||||
|
d="M 9.257812 -6.929688 L 9.257812 -15.804688 L 2.980469 -6.929688 Z M 9.296875 0 L 9.296875 -4.785156 L 0.710938 -4.785156 L 0.710938 -7.191406 L 9.679688 -19.632812 L 11.757812 -19.632812 L 11.757812 -6.929688 L 14.640625 -6.929688 L 14.640625 -4.785156 L 11.757812 -4.785156 L 11.757812 0 Z M 9.296875 0 "
|
||||||
|
id="path14" />
|
||||||
|
</symbol>
|
||||||
|
</g>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
id="surface11">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke-width:28;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(72.941176%,72.941176%,72.941176%);stroke-opacity:1;stroke-miterlimit:10;"
|
||||||
|
d="M 40 40 L 160 160 M 40 160 L 160 40 "
|
||||||
|
id="path21" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;"
|
||||||
|
d="M 188 160 C 188 175.464844 175.464844 188 160 188 C 144.535156 188 132 175.464844 132 160 C 132 144.535156 144.535156 132 160 132 C 175.464844 132 188 144.535156 188 160 M 179.800781 179.800781 L 177.785156 163 M 179.800781 179.800781 L 196.601562 179.800781 "
|
||||||
|
id="path23" />
|
||||||
|
<g
|
||||||
|
style="fill:rgb(0%,0%,0%);fill-opacity:1;"
|
||||||
|
id="g27" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;"
|
||||||
|
d="M 188 40 C 188 55.464844 175.464844 68 160 68 C 144.535156 68 132 55.464844 132 40 C 132 24.535156 144.535156 12 160 12 C 175.464844 12 188 24.535156 188 40 M 179.800781 20.199219 L 177.785156 37 M 179.800781 20.199219 L 196.601562 20.199219 "
|
||||||
|
id="path29" />
|
||||||
|
<g
|
||||||
|
style="fill:rgb(0%,0%,0%);fill-opacity:1;"
|
||||||
|
id="g33" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;"
|
||||||
|
d="M 68 160 C 68 175.464844 55.464844 188 40 188 C 24.535156 188 12 175.464844 12 160 C 12 144.535156 24.535156 132 40 132 C 55.464844 132 68 144.535156 68 160 M 20.199219 179.800781 L 22.214844 163 M 20.199219 179.800781 L 3.398438 179.800781 "
|
||||||
|
id="path35" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;"
|
||||||
|
d="M 68 40 C 68 55.464844 55.464844 68 40 68 C 24.535156 68 12 55.464844 12 40 C 12 24.535156 24.535156 12 40 12 C 55.464844 12 68 24.535156 68 40 M 20.199219 20.199219 L 22.214844 37 M 20.199219 20.199219 L 3.398438 20.199219 "
|
||||||
|
id="path41" />
|
||||||
|
<g
|
||||||
|
style="fill:rgb(0%,0%,0%);fill-opacity:1;"
|
||||||
|
id="g45" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke-width:12;stroke-linecap:butt;stroke-linejoin:bevel;stroke:rgb(98.039216%,2.745098%,0%);stroke-opacity:1;stroke-miterlimit:10;"
|
||||||
|
d="M 100 80 L 100 120 "
|
||||||
|
id="path47" />
|
||||||
|
<path
|
||||||
|
style=" stroke:none;fill-rule:nonzero;fill:rgb(98.039216%,2.745098%,0%);fill-opacity:1;"
|
||||||
|
d="M 100 75 L 85 90 L 115 90 L 100 75 "
|
||||||
|
id="path49" />
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 7.9 KiB |
|
@ -8,10 +8,9 @@
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg52"
|
id="svg52"
|
||||||
sodipodi:docname="quad_x_reverse.svg"
|
sodipodi:docname="quad_x_reverse.svg"
|
||||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
<sodipodi:namedview
|
<sodipodi:namedview
|
||||||
|
@ -25,14 +24,14 @@
|
||||||
inkscape:document-units="pt"
|
inkscape:document-units="pt"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:zoom="1.1269514"
|
inkscape:zoom="1.1269514"
|
||||||
inkscape:cx="-5.3240981"
|
inkscape:cx="-4.8804234"
|
||||||
inkscape:cy="231.15459"
|
inkscape:cy="231.1546"
|
||||||
inkscape:window-width="1920"
|
inkscape:window-width="1850"
|
||||||
inkscape:window-height="1009"
|
inkscape:window-height="1016"
|
||||||
inkscape:window-x="-8"
|
inkscape:window-x="1990"
|
||||||
inkscape:window-y="-8"
|
inkscape:window-y="27"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="svg52" />
|
inkscape:current-layer="g862" />
|
||||||
<defs
|
<defs
|
||||||
id="defs19">
|
id="defs19">
|
||||||
<g
|
<g
|
||||||
|
@ -89,62 +88,18 @@
|
||||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
||||||
d="m 188,160 c 0,-15.46484 -12.53516,-28 -28,-28 -15.46484,0 -28,12.53516 -28,28 0,15.46484 12.53516,28 28,28 15.46484,0 28,-12.53516 28,-28 M 179.80078,140.19922 177.78516,157 m 2.01562,-16.80078 h 16.80078"
|
d="m 188,160 c 0,-15.46484 -12.53516,-28 -28,-28 -15.46484,0 -28,12.53516 -28,28 0,15.46484 12.53516,28 28,28 15.46484,0 28,-12.53516 28,-28 M 179.80078,140.19922 177.78516,157 m 2.01562,-16.80078 h 16.80078"
|
||||||
id="path23" />
|
id="path23" />
|
||||||
<g
|
|
||||||
style="fill:#000000;fill-opacity:1"
|
|
||||||
id="g27">
|
|
||||||
<use
|
|
||||||
xlink:href="#glyph0-1"
|
|
||||||
x="153"
|
|
||||||
y="167"
|
|
||||||
id="use25"
|
|
||||||
width="100%"
|
|
||||||
height="100%" />
|
|
||||||
</g>
|
|
||||||
<path
|
<path
|
||||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
||||||
d="m 188,40 c 0,-15.464844 -12.53516,-28 -28,-28 -15.46484,0 -28,12.535156 -28,28 0,15.464844 12.53516,28 28,28 15.46484,0 28,-12.535156 28,-28 M 179.80078,59.800781 177.78516,43 m 2.01562,16.800781 h 16.80078"
|
d="m 188,40 c 0,-15.464844 -12.53516,-28 -28,-28 -15.46484,0 -28,12.535156 -28,28 0,15.464844 12.53516,28 28,28 15.46484,0 28,-12.535156 28,-28 M 179.80078,59.800781 177.78516,43 m 2.01562,16.800781 h 16.80078"
|
||||||
id="path29" />
|
id="path29" />
|
||||||
<g
|
|
||||||
style="fill:#000000;fill-opacity:1"
|
|
||||||
id="g33">
|
|
||||||
<use
|
|
||||||
xlink:href="#glyph0-2"
|
|
||||||
x="153"
|
|
||||||
y="47"
|
|
||||||
id="use31"
|
|
||||||
width="100%"
|
|
||||||
height="100%" />
|
|
||||||
</g>
|
|
||||||
<path
|
<path
|
||||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
||||||
d="m 68,160 c 0,-15.46484 -12.535156,-28 -28,-28 -15.464844,0 -28,12.53516 -28,28 0,15.46484 12.535156,28 28,28 15.464844,0 28,-12.53516 28,-28 M 20.199219,140.19922 22.214844,157 M 20.199219,140.19922 H 3.398438"
|
d="m 68,160 c 0,-15.46484 -12.535156,-28 -28,-28 -15.464844,0 -28,12.53516 -28,28 0,15.46484 12.535156,28 28,28 15.464844,0 28,-12.53516 28,-28 M 20.199219,140.19922 22.214844,157 M 20.199219,140.19922 H 3.398438"
|
||||||
id="path35" />
|
id="path35" />
|
||||||
<g
|
|
||||||
style="fill:#000000;fill-opacity:1"
|
|
||||||
id="g39">
|
|
||||||
<use
|
|
||||||
xlink:href="#glyph0-3"
|
|
||||||
x="33"
|
|
||||||
y="167"
|
|
||||||
id="use37"
|
|
||||||
width="100%"
|
|
||||||
height="100%" />
|
|
||||||
</g>
|
|
||||||
<path
|
<path
|
||||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
||||||
d="M 68,40 C 68,24.535156 55.464844,12 40,12 24.535156,12 12,24.535156 12,40 12,55.464844 24.535156,68 40,68 55.464844,68 68,55.464844 68,40 M 20.199219,59.800781 22.214844,43 M 20.199219,59.800781 H 3.398438"
|
d="M 68,40 C 68,24.535156 55.464844,12 40,12 24.535156,12 12,24.535156 12,40 12,55.464844 24.535156,68 40,68 55.464844,68 68,55.464844 68,40 M 20.199219,59.800781 22.214844,43 M 20.199219,59.800781 H 3.398438"
|
||||||
id="path41" />
|
id="path41" />
|
||||||
<g
|
|
||||||
style="fill:#000000;fill-opacity:1"
|
|
||||||
id="g45">
|
|
||||||
<use
|
|
||||||
xlink:href="#glyph0-4"
|
|
||||||
x="33"
|
|
||||||
y="47"
|
|
||||||
id="use43"
|
|
||||||
width="100%"
|
|
||||||
height="100%" />
|
|
||||||
</g>
|
|
||||||
<path
|
<path
|
||||||
style="fill:none;stroke:#fa0500;stroke-width:12;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-opacity:1"
|
style="fill:none;stroke:#fa0500;stroke-width:12;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-opacity:1"
|
||||||
d="m 100,80 v 40"
|
d="m 100,80 v 40"
|
||||||
|
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 7.5 KiB |
|
@ -1,51 +1,38 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!-- Public domain (CC-BY-SA if you or your laws insist), generated by Jonathan Hudson's svg_model_motors.rb -->
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200pt" height="200pt" viewBox="0 0 200 200" version="1.1">
|
<svg width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;">
|
||||||
<defs>
|
<g id="surface6">
|
||||||
<g>
|
<path d="M40,40L160,40M100,40L100,160" style="fill:none;fill-rule:nonzero;stroke:rgb(185,185,185);stroke-width:28px;"/>
|
||||||
<symbol overflow="visible" id="glyph0-0">
|
<path d="M128,160C128,175.465 115.465,188 100,188C84.535,188 72,175.465 72,160C72,144.535 84.535,132 100,132C115.465,132 128,144.535 128,160M80.199,140.199L80.199,123.398M80.199,140.199L97,142.215" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||||
<path style="stroke:none;" d=""/>
|
<g id="glyph0-1" transform="matrix(1,0,0,1,93,167)">
|
||||||
</symbol>
|
<g>
|
||||||
<symbol overflow="visible" id="glyph0-1">
|
<path d="M2.68,-13.863L2.68,-15.75C4.457,-15.922 5.695,-16.211 6.398,-16.617C7.102,-17.023 7.625,-17.984 7.969,-19.496L9.914,-19.496L9.914,0L7.289,0L7.289,-13.863L2.68,-13.863Z" style="fill-rule:nonzero;"/>
|
||||||
<path style="stroke:none;" d="M 2.679688 -13.863281 L 2.679688 -15.75 C 4.457031 -15.921875 5.695312 -16.210938 6.398438 -16.617188 C 7.101562 -17.023438 7.625 -17.984375 7.96875 -19.496094 L 9.914062 -19.496094 L 9.914062 0 L 7.289062 0 L 7.289062 -13.863281 Z M 2.679688 -13.863281 "/>
|
</g>
|
||||||
</symbol>
|
</g>
|
||||||
<symbol overflow="visible" id="glyph0-2">
|
<path d="M188,40C188,55.465 175.465,68 160,68C144.535,68 132,55.465 132,40C132,24.535 144.535,12 160,12C175.465,12 188,24.535 188,40M140.199,20.199L140.199,3.398M140.199,20.199L157,22.215" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||||
<path style="stroke:none;" d="M 1.921875 -4.402344 C 2.527344 -5.652344 3.710938 -6.785156 5.46875 -7.804688 L 8.09375 -9.324219 C 9.269531 -10.007812 10.09375 -10.589844 10.570312 -11.074219 C 11.316406 -11.832031 11.6875 -12.695312 11.6875 -13.671875 C 11.6875 -14.8125 11.347656 -15.714844 10.664062 -16.386719 C 9.980469 -17.054688 9.070312 -17.390625 7.929688 -17.390625 C 6.242188 -17.390625 5.078125 -16.753906 4.429688 -15.476562 C 4.082031 -14.792969 3.890625 -13.84375 3.855469 -12.632812 L 1.351562 -12.632812 C 1.378906 -14.335938 1.695312 -15.726562 2.296875 -16.804688 C 3.363281 -18.699219 5.246094 -19.648438 7.945312 -19.648438 C 10.1875 -19.648438 11.824219 -19.039062 12.859375 -17.828125 C 13.894531 -16.617188 14.410156 -15.265625 14.410156 -13.78125 C 14.410156 -12.214844 13.859375 -10.875 12.757812 -9.761719 C 12.117188 -9.113281 10.972656 -8.332031 9.324219 -7.410156 L 7.453125 -6.371094 C 6.558594 -5.878906 5.855469 -5.410156 5.34375 -4.960938 C 4.433594 -4.167969 3.859375 -3.289062 3.625 -2.324219 L 14.3125 -2.324219 L 14.3125 0 L 0.875 0 C 0.964844 -1.6875 1.316406 -3.152344 1.921875 -4.402344 Z M 1.921875 -4.402344 "/>
|
<g id="glyph0-2" transform="matrix(1,0,0,1,153,47)">
|
||||||
</symbol>
|
<g>
|
||||||
<symbol overflow="visible" id="glyph0-3">
|
<path d="M1.922,-4.402C2.527,-5.652 3.711,-6.785 5.469,-7.805L8.094,-9.324C9.27,-10.008 10.094,-10.59 10.57,-11.074C11.316,-11.832 11.688,-12.695 11.688,-13.672C11.688,-14.813 11.348,-15.715 10.664,-16.387C9.98,-17.055 9.07,-17.391 7.93,-17.391C6.242,-17.391 5.078,-16.754 4.43,-15.477C4.082,-14.793 3.891,-13.844 3.855,-12.633L1.352,-12.633C1.379,-14.336 1.695,-15.727 2.297,-16.805C3.363,-18.699 5.246,-19.648 7.945,-19.648C10.188,-19.648 11.824,-19.039 12.859,-17.828C13.895,-16.617 14.41,-15.266 14.41,-13.781C14.41,-12.215 13.859,-10.875 12.758,-9.762C12.117,-9.113 10.973,-8.332 9.324,-7.41L7.453,-6.371C6.559,-5.879 5.855,-5.41 5.344,-4.961C4.434,-4.168 3.859,-3.289 3.625,-2.324L14.313,-2.324L14.313,0L0.875,0C0.965,-1.688 1.316,-3.152 1.922,-4.402Z" style="fill-rule:nonzero;"/>
|
||||||
<path style="stroke:none;" d="M 2.234375 -1.375 C 1.191406 -2.644531 0.671875 -4.191406 0.671875 -6.015625 L 3.242188 -6.015625 C 3.351562 -4.75 3.585938 -3.828125 3.953125 -3.253906 C 4.589844 -2.222656 5.742188 -1.710938 7.410156 -1.710938 C 8.703125 -1.710938 9.742188 -2.054688 10.527344 -2.75 C 11.3125 -3.441406 11.703125 -4.335938 11.703125 -5.429688 C 11.703125 -6.777344 11.289062 -7.71875 10.464844 -8.257812 C 9.640625 -8.796875 8.496094 -9.0625 7.027344 -9.0625 C 6.863281 -9.0625 6.695312 -9.0625 6.527344 -9.058594 C 6.359375 -9.054688 6.1875 -9.046875 6.015625 -9.039062 L 6.015625 -11.210938 C 6.269531 -11.183594 6.484375 -11.164062 6.65625 -11.15625 C 6.832031 -11.148438 7.019531 -11.140625 7.21875 -11.140625 C 8.140625 -11.140625 8.894531 -11.289062 9.488281 -11.578125 C 10.527344 -12.089844 11.046875 -13 11.046875 -14.3125 C 11.046875 -15.289062 10.699219 -16.042969 10.007812 -16.570312 C 9.316406 -17.097656 8.507812 -17.363281 7.585938 -17.363281 C 5.945312 -17.363281 4.8125 -16.816406 4.183594 -15.722656 C 3.835938 -15.121094 3.640625 -14.265625 3.59375 -13.152344 L 1.164062 -13.152344 C 1.164062 -14.609375 1.453125 -15.851562 2.039062 -16.871094 C 3.039062 -18.695312 4.804688 -19.605469 7.328125 -19.605469 C 9.324219 -19.605469 10.867188 -19.160156 11.960938 -18.273438 C 13.054688 -17.382812 13.601562 -16.097656 13.601562 -14.410156 C 13.601562 -13.207031 13.28125 -12.230469 12.632812 -11.484375 C 12.230469 -11.019531 11.710938 -10.65625 11.074219 -10.390625 C 12.105469 -10.109375 12.910156 -9.5625 13.488281 -8.757812 C 14.066406 -7.949219 14.355469 -6.964844 14.355469 -5.796875 C 14.355469 -3.929688 13.742188 -2.40625 12.507812 -1.230469 C 11.277344 -0.0546875 9.535156 0.53125 7.273438 0.53125 C 4.957031 0.53125 3.277344 -0.101562 2.234375 -1.375 Z M 2.234375 -1.375 "/>
|
</g>
|
||||||
</symbol>
|
</g>
|
||||||
<symbol overflow="visible" id="glyph1-0">
|
<g transform="matrix(0.0166389,-0.999862,-0.999862,-0.0166389,80.5581,80.9602)">
|
||||||
<path style="stroke:none;" d=""/>
|
<path d="M68,40C68,55.465 55.465,68 40,68C24.535,68 12,55.465 12,40C12,24.535 24.535,12 40,12C55.465,12 68,24.535 68,40M59.801,20.199L57.785,37M59.801,20.199L76.602,20.199" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||||
</symbol>
|
</g>
|
||||||
<symbol overflow="visible" id="glyph1-1">
|
<g id="glyph0-3" transform="matrix(1,0,0,1,33,47)">
|
||||||
<path style="stroke:none;" d="M 2.234375 -3.703125 C 2.269531 -3.050781 2.425781 -2.523438 2.695312 -2.117188 C 3.210938 -1.355469 4.121094 -0.976562 5.421875 -0.976562 C 6.003906 -0.976562 6.535156 -1.058594 7.015625 -1.226562 C 7.941406 -1.550781 8.40625 -2.128906 8.40625 -2.960938 C 8.40625 -3.585938 8.210938 -4.03125 7.820312 -4.296875 C 7.425781 -4.558594 6.804688 -4.785156 5.960938 -4.976562 L 4.40625 -5.328125 C 3.390625 -5.558594 2.671875 -5.808594 2.25 -6.085938 C 1.519531 -6.566406 1.15625 -7.28125 1.15625 -8.234375 C 1.15625 -9.265625 1.511719 -10.113281 2.226562 -10.773438 C 2.941406 -11.433594 3.949219 -11.765625 5.257812 -11.765625 C 6.460938 -11.765625 7.484375 -11.476562 8.324219 -10.894531 C 9.164062 -10.3125 9.585938 -9.386719 9.585938 -8.109375 L 8.125 -8.109375 C 8.046875 -8.722656 7.878906 -9.195312 7.625 -9.523438 C 7.152344 -10.121094 6.347656 -10.421875 5.210938 -10.421875 C 4.292969 -10.421875 3.636719 -10.230469 3.234375 -9.84375 C 2.832031 -9.457031 2.632812 -9.011719 2.632812 -8.5 C 2.632812 -7.9375 2.867188 -7.527344 3.335938 -7.265625 C 3.644531 -7.097656 4.339844 -6.890625 5.421875 -6.640625 L 7.03125 -6.273438 C 7.808594 -6.097656 8.40625 -5.855469 8.828125 -5.546875 C 9.558594 -5.011719 9.921875 -4.230469 9.921875 -3.210938 C 9.921875 -1.941406 9.460938 -1.03125 8.535156 -0.484375 C 7.609375 0.0625 6.535156 0.335938 5.3125 0.335938 C 3.886719 0.335938 2.769531 -0.0273438 1.960938 -0.757812 C 1.152344 -1.480469 0.757812 -2.464844 0.773438 -3.703125 Z M 2.234375 -3.703125 "/>
|
<g>
|
||||||
</symbol>
|
<path d="M2.234,-1.375C1.191,-2.645 0.672,-4.191 0.672,-6.016L3.242,-6.016C3.352,-4.75 3.586,-3.828 3.953,-3.254C4.59,-2.223 5.742,-1.711 7.41,-1.711C8.703,-1.711 9.742,-2.055 10.527,-2.75C11.313,-3.441 11.703,-4.336 11.703,-5.43C11.703,-6.777 11.289,-7.719 10.465,-8.258C9.641,-8.797 8.496,-9.063 7.027,-9.063C6.863,-9.063 6.695,-9.063 6.527,-9.059C6.359,-9.055 6.188,-9.047 6.016,-9.039L6.016,-11.211C6.27,-11.184 6.484,-11.164 6.656,-11.156C6.832,-11.148 7.02,-11.141 7.219,-11.141C8.141,-11.141 8.895,-11.289 9.488,-11.578C10.527,-12.09 11.047,-13 11.047,-14.313C11.047,-15.289 10.699,-16.043 10.008,-16.57C9.316,-17.098 8.508,-17.363 7.586,-17.363C5.945,-17.363 4.813,-16.816 4.184,-15.723C3.836,-15.121 3.641,-14.266 3.594,-13.152L1.164,-13.152C1.164,-14.609 1.453,-15.852 2.039,-16.871C3.039,-18.695 4.805,-19.605 7.328,-19.605C9.324,-19.605 10.867,-19.16 11.961,-18.273C13.055,-17.383 13.602,-16.098 13.602,-14.41C13.602,-13.207 13.281,-12.23 12.633,-11.484C12.23,-11.02 11.711,-10.656 11.074,-10.391C12.105,-10.109 12.91,-9.563 13.488,-8.758C14.066,-7.949 14.355,-6.965 14.355,-5.797C14.355,-3.93 13.742,-2.406 12.508,-1.23C11.277,-0.055 9.535,0.531 7.273,0.531C4.957,0.531 3.277,-0.102 2.234,-1.375Z" style="fill-rule:nonzero;"/>
|
||||||
<symbol overflow="visible" id="glyph1-2">
|
</g>
|
||||||
<path style="stroke:none;" d="M 1.53125 -7.921875 L 1.53125 -9 C 2.546875 -9.097656 3.253906 -9.265625 3.65625 -9.496094 C 4.058594 -9.726562 4.355469 -10.277344 4.554688 -11.140625 L 5.664062 -11.140625 L 5.664062 0 L 4.164062 0 L 4.164062 -7.921875 Z M 1.53125 -7.921875 "/>
|
</g>
|
||||||
</symbol>
|
<rect x="140" y="140" width="28" height="28" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||||
</g>
|
<g>
|
||||||
</defs>
|
<g id="glyph1-1" transform="matrix(1,0,0,1,144,160)">
|
||||||
<g id="surface6">
|
<path d="M2.234,-3.703C2.27,-3.051 2.426,-2.523 2.695,-2.117C3.211,-1.355 4.121,-0.977 5.422,-0.977C6.004,-0.977 6.535,-1.059 7.016,-1.227C7.941,-1.551 8.406,-2.129 8.406,-2.961C8.406,-3.586 8.211,-4.031 7.82,-4.297C7.426,-4.559 6.805,-4.785 5.961,-4.977L4.406,-5.328C3.391,-5.559 2.672,-5.809 2.25,-6.086C1.52,-6.566 1.156,-7.281 1.156,-8.234C1.156,-9.266 1.512,-10.113 2.227,-10.773C2.941,-11.434 3.949,-11.766 5.258,-11.766C6.461,-11.766 7.484,-11.477 8.324,-10.895C9.164,-10.313 9.586,-9.387 9.586,-8.109L8.125,-8.109C8.047,-8.723 7.879,-9.195 7.625,-9.523C7.152,-10.121 6.348,-10.422 5.211,-10.422C4.293,-10.422 3.637,-10.23 3.234,-9.844C2.832,-9.457 2.633,-9.012 2.633,-8.5C2.633,-7.938 2.867,-7.527 3.336,-7.266C3.645,-7.098 4.34,-6.891 5.422,-6.641L7.031,-6.273C7.809,-6.098 8.406,-5.855 8.828,-5.547C9.559,-5.012 9.922,-4.23 9.922,-3.211C9.922,-1.941 9.461,-1.031 8.535,-0.484C7.609,0.063 6.535,0.336 5.313,0.336C3.887,0.336 2.77,-0.027 1.961,-0.758C1.152,-1.48 0.758,-2.465 0.773,-3.703L2.234,-3.703Z" style="fill-rule:nonzero;"/>
|
||||||
<path style="fill:none;stroke-width:28;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(72.941176%,72.941176%,72.941176%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40 40 L 160 40 M 100 40 L 100 160 "/>
|
</g>
|
||||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 128 160 C 128 175.464844 115.464844 188 100 188 C 84.535156 188 72 175.464844 72 160 C 72 144.535156 84.535156 132 100 132 C 115.464844 132 128 144.535156 128 160 M 80.199219 140.199219 L 80.199219 123.398438 M 80.199219 140.199219 L 97 142.214844 "/>
|
<g id="glyph1-2" transform="matrix(1,0,0,1,154.672,160)">
|
||||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
<path d="M1.531,-7.922L1.531,-9C2.547,-9.098 3.254,-9.266 3.656,-9.496C4.059,-9.727 4.355,-10.277 4.555,-11.141L5.664,-11.141L5.664,0L4.164,0L4.164,-7.922L1.531,-7.922Z" style="fill-rule:nonzero;"/>
|
||||||
<use xlink:href="#glyph0-1" x="93" y="167"/>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 188 40 C 188 55.464844 175.464844 68 160 68 C 144.535156 68 132 55.464844 132 40 C 132 24.535156 144.535156 12 160 12 C 175.464844 12 188 24.535156 188 40 M 140.199219 20.199219 L 140.199219 3.398438 M 140.199219 20.199219 L 157 22.214844 "/>
|
<path d="M100,70L100,110" style="fill:none;fill-rule:nonzero;stroke:rgb(250,6,0);stroke-width:12px;stroke-linecap:butt;stroke-linejoin:bevel;"/>
|
||||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
<path d="M100,65L85,80L115,80L100,65" style="fill:rgb(250,6,0);fill-rule:nonzero;"/>
|
||||||
<use xlink:href="#glyph0-2" x="153" y="47"/>
|
</g>
|
||||||
</g>
|
|
||||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 68 40 C 68 55.464844 55.464844 68 40 68 C 24.535156 68 12 55.464844 12 40 C 12 24.535156 24.535156 12 40 12 C 55.464844 12 68 24.535156 68 40 M 59.800781 20.199219 L 57.785156 37 M 59.800781 20.199219 L 76.601562 20.199219 "/>
|
|
||||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
||||||
<use xlink:href="#glyph0-3" x="33" y="47"/>
|
|
||||||
</g>
|
|
||||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 140 140 L 168 140 L 168 168 L 140 168 Z M 140 140 "/>
|
|
||||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
||||||
<use xlink:href="#glyph1-1" x="144" y="160"/>
|
|
||||||
<use xlink:href="#glyph1-2" x="154.671875" y="160"/>
|
|
||||||
</g>
|
|
||||||
<path style="fill:none;stroke-width:12;stroke-linecap:butt;stroke-linejoin:bevel;stroke:rgb(98.039216%,2.745098%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 100 70 L 100 110 "/>
|
|
||||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(98.039216%,2.745098%,0%);fill-opacity:1;" d="M 100 65 L 85 80 L 115 80 L 100 65 "/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 8 KiB After Width: | Height: | Size: 6 KiB |
|
@ -1,177 +1,42 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!-- Public domain (CC-BY-SA if you or your laws insist), generated by Jonathan Hudson's svg_model_motors.rb -->
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;">
|
||||||
<svg
|
<path id="path27" d="M40,40L160,40M100,40L100,160" style="fill:none;fill-rule:nonzero;stroke:rgb(184,184,184);stroke-width:28px;"/>
|
||||||
width="200pt"
|
<path id="path29" d="M72,160C72,175.465 84.535,188 100,188C115.465,188 128,175.465 128,160C128,144.535 115.465,132 100,132C84.535,132 72,144.535 72,160M119.801,140.199L119.801,123.398M119.801,140.199L103,142.215" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||||
height="200pt"
|
<g id="use31" transform="matrix(1,0,0,1,93,167)">
|
||||||
viewBox="0 0 200 200"
|
<g id="g33">
|
||||||
version="1.1"
|
<g id="use311" serif:id="use31">
|
||||||
id="svg60"
|
<path id="path5" d="M2.68,-13.863L2.68,-15.75C4.457,-15.922 5.695,-16.211 6.398,-16.617C7.102,-17.023 7.625,-17.984 7.969,-19.496L9.914,-19.496L9.914,0L7.289,0L7.289,-13.863L2.68,-13.863Z" style="fill-rule:nonzero;"/>
|
||||||
sodipodi:docname="tri_reverse.svg"
|
</g>
|
||||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
</g>
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview62"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:pageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:document-units="pt"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="3.1875"
|
|
||||||
inkscape:cx="133.33333"
|
|
||||||
inkscape:cy="108.39216"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1009"
|
|
||||||
inkscape:window-x="1912"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg60" />
|
|
||||||
<defs
|
|
||||||
id="defs25">
|
|
||||||
<g
|
|
||||||
id="g23">
|
|
||||||
<symbol
|
|
||||||
overflow="visible"
|
|
||||||
id="glyph0-0">
|
|
||||||
<path
|
|
||||||
style="stroke:none;"
|
|
||||||
d=""
|
|
||||||
id="path2" />
|
|
||||||
</symbol>
|
|
||||||
<symbol
|
|
||||||
overflow="visible"
|
|
||||||
id="glyph0-1">
|
|
||||||
<path
|
|
||||||
style="stroke:none;"
|
|
||||||
d="M 2.679688 -13.863281 L 2.679688 -15.75 C 4.457031 -15.921875 5.695312 -16.210938 6.398438 -16.617188 C 7.101562 -17.023438 7.625 -17.984375 7.96875 -19.496094 L 9.914062 -19.496094 L 9.914062 0 L 7.289062 0 L 7.289062 -13.863281 Z M 2.679688 -13.863281 "
|
|
||||||
id="path5" />
|
|
||||||
</symbol>
|
|
||||||
<symbol
|
|
||||||
overflow="visible"
|
|
||||||
id="glyph0-2">
|
|
||||||
<path
|
|
||||||
style="stroke:none;"
|
|
||||||
d="M 1.921875 -4.402344 C 2.527344 -5.652344 3.710938 -6.785156 5.46875 -7.804688 L 8.09375 -9.324219 C 9.269531 -10.007812 10.09375 -10.589844 10.570312 -11.074219 C 11.316406 -11.832031 11.6875 -12.695312 11.6875 -13.671875 C 11.6875 -14.8125 11.347656 -15.714844 10.664062 -16.386719 C 9.980469 -17.054688 9.070312 -17.390625 7.929688 -17.390625 C 6.242188 -17.390625 5.078125 -16.753906 4.429688 -15.476562 C 4.082031 -14.792969 3.890625 -13.84375 3.855469 -12.632812 L 1.351562 -12.632812 C 1.378906 -14.335938 1.695312 -15.726562 2.296875 -16.804688 C 3.363281 -18.699219 5.246094 -19.648438 7.945312 -19.648438 C 10.1875 -19.648438 11.824219 -19.039062 12.859375 -17.828125 C 13.894531 -16.617188 14.410156 -15.265625 14.410156 -13.78125 C 14.410156 -12.214844 13.859375 -10.875 12.757812 -9.761719 C 12.117188 -9.113281 10.972656 -8.332031 9.324219 -7.410156 L 7.453125 -6.371094 C 6.558594 -5.878906 5.855469 -5.410156 5.34375 -4.960938 C 4.433594 -4.167969 3.859375 -3.289062 3.625 -2.324219 L 14.3125 -2.324219 L 14.3125 0 L 0.875 0 C 0.964844 -1.6875 1.316406 -3.152344 1.921875 -4.402344 Z M 1.921875 -4.402344 "
|
|
||||||
id="path8" />
|
|
||||||
</symbol>
|
|
||||||
<symbol
|
|
||||||
overflow="visible"
|
|
||||||
id="glyph0-3">
|
|
||||||
<path
|
|
||||||
style="stroke:none;"
|
|
||||||
d="M 2.234375 -1.375 C 1.191406 -2.644531 0.671875 -4.191406 0.671875 -6.015625 L 3.242188 -6.015625 C 3.351562 -4.75 3.585938 -3.828125 3.953125 -3.253906 C 4.589844 -2.222656 5.742188 -1.710938 7.410156 -1.710938 C 8.703125 -1.710938 9.742188 -2.054688 10.527344 -2.75 C 11.3125 -3.441406 11.703125 -4.335938 11.703125 -5.429688 C 11.703125 -6.777344 11.289062 -7.71875 10.464844 -8.257812 C 9.640625 -8.796875 8.496094 -9.0625 7.027344 -9.0625 C 6.863281 -9.0625 6.695312 -9.0625 6.527344 -9.058594 C 6.359375 -9.054688 6.1875 -9.046875 6.015625 -9.039062 L 6.015625 -11.210938 C 6.269531 -11.183594 6.484375 -11.164062 6.65625 -11.15625 C 6.832031 -11.148438 7.019531 -11.140625 7.21875 -11.140625 C 8.140625 -11.140625 8.894531 -11.289062 9.488281 -11.578125 C 10.527344 -12.089844 11.046875 -13 11.046875 -14.3125 C 11.046875 -15.289062 10.699219 -16.042969 10.007812 -16.570312 C 9.316406 -17.097656 8.507812 -17.363281 7.585938 -17.363281 C 5.945312 -17.363281 4.8125 -16.816406 4.183594 -15.722656 C 3.835938 -15.121094 3.640625 -14.265625 3.59375 -13.152344 L 1.164062 -13.152344 C 1.164062 -14.609375 1.453125 -15.851562 2.039062 -16.871094 C 3.039062 -18.695312 4.804688 -19.605469 7.328125 -19.605469 C 9.324219 -19.605469 10.867188 -19.160156 11.960938 -18.273438 C 13.054688 -17.382812 13.601562 -16.097656 13.601562 -14.410156 C 13.601562 -13.207031 13.28125 -12.230469 12.632812 -11.484375 C 12.230469 -11.019531 11.710938 -10.65625 11.074219 -10.390625 C 12.105469 -10.109375 12.910156 -9.5625 13.488281 -8.757812 C 14.066406 -7.949219 14.355469 -6.964844 14.355469 -5.796875 C 14.355469 -3.929688 13.742188 -2.40625 12.507812 -1.230469 C 11.277344 -0.0546875 9.535156 0.53125 7.273438 0.53125 C 4.957031 0.53125 3.277344 -0.101562 2.234375 -1.375 Z M 2.234375 -1.375 "
|
|
||||||
id="path11" />
|
|
||||||
</symbol>
|
|
||||||
<symbol
|
|
||||||
overflow="visible"
|
|
||||||
id="glyph1-0">
|
|
||||||
<path
|
|
||||||
style="stroke:none;"
|
|
||||||
d=""
|
|
||||||
id="path14" />
|
|
||||||
</symbol>
|
|
||||||
<symbol
|
|
||||||
overflow="visible"
|
|
||||||
id="glyph1-1">
|
|
||||||
<path
|
|
||||||
style="stroke:none;"
|
|
||||||
d="M 2.234375 -3.703125 C 2.269531 -3.050781 2.425781 -2.523438 2.695312 -2.117188 C 3.210938 -1.355469 4.121094 -0.976562 5.421875 -0.976562 C 6.003906 -0.976562 6.535156 -1.058594 7.015625 -1.226562 C 7.941406 -1.550781 8.40625 -2.128906 8.40625 -2.960938 C 8.40625 -3.585938 8.210938 -4.03125 7.820312 -4.296875 C 7.425781 -4.558594 6.804688 -4.785156 5.960938 -4.976562 L 4.40625 -5.328125 C 3.390625 -5.558594 2.671875 -5.808594 2.25 -6.085938 C 1.519531 -6.566406 1.15625 -7.28125 1.15625 -8.234375 C 1.15625 -9.265625 1.511719 -10.113281 2.226562 -10.773438 C 2.941406 -11.433594 3.949219 -11.765625 5.257812 -11.765625 C 6.460938 -11.765625 7.484375 -11.476562 8.324219 -10.894531 C 9.164062 -10.3125 9.585938 -9.386719 9.585938 -8.109375 L 8.125 -8.109375 C 8.046875 -8.722656 7.878906 -9.195312 7.625 -9.523438 C 7.152344 -10.121094 6.347656 -10.421875 5.210938 -10.421875 C 4.292969 -10.421875 3.636719 -10.230469 3.234375 -9.84375 C 2.832031 -9.457031 2.632812 -9.011719 2.632812 -8.5 C 2.632812 -7.9375 2.867188 -7.527344 3.335938 -7.265625 C 3.644531 -7.097656 4.339844 -6.890625 5.421875 -6.640625 L 7.03125 -6.273438 C 7.808594 -6.097656 8.40625 -5.855469 8.828125 -5.546875 C 9.558594 -5.011719 9.921875 -4.230469 9.921875 -3.210938 C 9.921875 -1.941406 9.460938 -1.03125 8.535156 -0.484375 C 7.609375 0.0625 6.535156 0.335938 5.3125 0.335938 C 3.886719 0.335938 2.769531 -0.0273438 1.960938 -0.757812 C 1.152344 -1.480469 0.757812 -2.464844 0.773438 -3.703125 Z M 2.234375 -3.703125 "
|
|
||||||
id="path17" />
|
|
||||||
</symbol>
|
|
||||||
<symbol
|
|
||||||
overflow="visible"
|
|
||||||
id="glyph1-2">
|
|
||||||
<path
|
|
||||||
style="stroke:none;"
|
|
||||||
d="M 1.53125 -7.921875 L 1.53125 -9 C 2.546875 -9.097656 3.253906 -9.265625 3.65625 -9.496094 C 4.058594 -9.726562 4.355469 -10.277344 4.554688 -11.140625 L 5.664062 -11.140625 L 5.664062 0 L 4.164062 0 L 4.164062 -7.921875 Z M 1.53125 -7.921875 "
|
|
||||||
id="path20" />
|
|
||||||
</symbol>
|
|
||||||
</g>
|
</g>
|
||||||
</defs>
|
<path id="path35-4" d="M132,40C132,55.465 144.535,68 160,68C175.465,68 188,55.465 188,40C188,24.535 175.465,12 160,12C144.535,12 132,24.535 132,40M179.801,20.199L179.801,3.398M179.801,20.199L163,22.215" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||||
<path
|
<g id="use37" transform="matrix(1,0,0,1,153,47)">
|
||||||
style="fill:none;stroke:#b8b8b8;stroke-width:28;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
<g id="g39">
|
||||||
d="m 40,40 h 120 m -60,0 v 120"
|
<g id="use371" serif:id="use37">
|
||||||
id="path27" />
|
<path id="path8" d="M1.922,-4.402C2.527,-5.652 3.711,-6.785 5.469,-7.805L8.094,-9.324C9.27,-10.008 10.094,-10.59 10.57,-11.074C11.316,-11.832 11.688,-12.695 11.688,-13.672C11.688,-14.813 11.348,-15.715 10.664,-16.387C9.98,-17.055 9.07,-17.391 7.93,-17.391C6.242,-17.391 5.078,-16.754 4.43,-15.477C4.082,-14.793 3.891,-13.844 3.855,-12.633L1.352,-12.633C1.379,-14.336 1.695,-15.727 2.297,-16.805C3.363,-18.699 5.246,-19.648 7.945,-19.648C10.188,-19.648 11.824,-19.039 12.859,-17.828C13.895,-16.617 14.41,-15.266 14.41,-13.781C14.41,-12.215 13.859,-10.875 12.758,-9.762C12.117,-9.113 10.973,-8.332 9.324,-7.41L7.453,-6.371C6.559,-5.879 5.855,-5.41 5.344,-4.961C4.434,-4.168 3.859,-3.289 3.625,-2.324L14.313,-2.324L14.313,0L0.875,0C0.965,-1.688 1.316,-3.152 1.922,-4.402Z" style="fill-rule:nonzero;"/>
|
||||||
<path
|
</g>
|
||||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
</g>
|
||||||
d="m 72,160 c 0,15.46484 12.53516,28 28,28 15.46484,0 28,-12.53516 28,-28 0,-15.46484 -12.53516,-28 -28,-28 -15.46484,0 -28,12.53516 -28,28 m 47.80078,-19.80078 v -16.80078 m 0,16.80078 L 103,142.21484"
|
</g>
|
||||||
id="path29" />
|
<g id="path41-0" transform="matrix(0.00137106,0.999999,0.999999,-0.00137106,1.45802,0.54821)">
|
||||||
<g
|
<path d="M11.807,40C11.807,55.465 24.343,68 39.807,68C55.272,68 67.807,55.465 67.807,40C67.807,24.535 55.272,12 39.807,12C24.343,12 11.807,24.535 11.807,40M20.007,20.199L22.022,37M20.007,20.199L3.206,20.199" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||||
style="fill:#000000;fill-opacity:1"
|
</g>
|
||||||
id="g33">
|
<g id="use43" transform="matrix(1,0,0,1,33,47)">
|
||||||
<use
|
<g id="g45">
|
||||||
xlink:href="#glyph0-1"
|
<g id="use431" serif:id="use43">
|
||||||
x="93"
|
<path id="path11" d="M2.234,-1.375C1.191,-2.645 0.672,-4.191 0.672,-6.016L3.242,-6.016C3.352,-4.75 3.586,-3.828 3.953,-3.254C4.59,-2.223 5.742,-1.711 7.41,-1.711C8.703,-1.711 9.742,-2.055 10.527,-2.75C11.313,-3.441 11.703,-4.336 11.703,-5.43C11.703,-6.777 11.289,-7.719 10.465,-8.258C9.641,-8.797 8.496,-9.063 7.027,-9.063C6.863,-9.063 6.695,-9.063 6.527,-9.059C6.359,-9.055 6.188,-9.047 6.016,-9.039L6.016,-11.211C6.27,-11.184 6.484,-11.164 6.656,-11.156C6.832,-11.148 7.02,-11.141 7.219,-11.141C8.141,-11.141 8.895,-11.289 9.488,-11.578C10.527,-12.09 11.047,-13 11.047,-14.313C11.047,-15.289 10.699,-16.043 10.008,-16.57C9.316,-17.098 8.508,-17.363 7.586,-17.363C5.945,-17.363 4.813,-16.816 4.184,-15.723C3.836,-15.121 3.641,-14.266 3.594,-13.152L1.164,-13.152C1.164,-14.609 1.453,-15.852 2.039,-16.871C3.039,-18.695 4.805,-19.605 7.328,-19.605C9.324,-19.605 10.867,-19.16 11.961,-18.273C13.055,-17.383 13.602,-16.098 13.602,-14.41C13.602,-13.207 13.281,-12.23 12.633,-11.484C12.23,-11.02 11.711,-10.656 11.074,-10.391C12.105,-10.109 12.91,-9.563 13.488,-8.758C14.066,-7.949 14.355,-6.965 14.355,-5.797C14.355,-3.93 13.742,-2.406 12.508,-1.23C11.277,-0.055 9.535,0.531 7.273,0.531C4.957,0.531 3.277,-0.102 2.234,-1.375Z" style="fill-rule:nonzero;"/>
|
||||||
y="167"
|
</g>
|
||||||
id="use31"
|
</g>
|
||||||
width="100%"
|
</g>
|
||||||
height="100%" />
|
<rect id="path47" x="140" y="140" width="28" height="28" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||||
</g>
|
<g id="g53">
|
||||||
<path
|
<g id="use49" transform="matrix(1,0,0,1,144,160)">
|
||||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
<path id="path17" d="M2.234,-3.703C2.27,-3.051 2.426,-2.523 2.695,-2.117C3.211,-1.355 4.121,-0.977 5.422,-0.977C6.004,-0.977 6.535,-1.059 7.016,-1.227C7.941,-1.551 8.406,-2.129 8.406,-2.961C8.406,-3.586 8.211,-4.031 7.82,-4.297C7.426,-4.559 6.805,-4.785 5.961,-4.977L4.406,-5.328C3.391,-5.559 2.672,-5.809 2.25,-6.086C1.52,-6.566 1.156,-7.281 1.156,-8.234C1.156,-9.266 1.512,-10.113 2.227,-10.773C2.941,-11.434 3.949,-11.766 5.258,-11.766C6.461,-11.766 7.484,-11.477 8.324,-10.895C9.164,-10.313 9.586,-9.387 9.586,-8.109L8.125,-8.109C8.047,-8.723 7.879,-9.195 7.625,-9.523C7.152,-10.121 6.348,-10.422 5.211,-10.422C4.293,-10.422 3.637,-10.23 3.234,-9.844C2.832,-9.457 2.633,-9.012 2.633,-8.5C2.633,-7.938 2.867,-7.527 3.336,-7.266C3.645,-7.098 4.34,-6.891 5.422,-6.641L7.031,-6.273C7.809,-6.098 8.406,-5.855 8.828,-5.547C9.559,-5.012 9.922,-4.23 9.922,-3.211C9.922,-1.941 9.461,-1.031 8.535,-0.484C7.609,0.063 6.535,0.336 5.313,0.336C3.887,0.336 2.77,-0.027 1.961,-0.758C1.152,-1.48 0.758,-2.465 0.773,-3.703L2.234,-3.703Z" style="fill-rule:nonzero;"/>
|
||||||
d="m 132,40 c 0,15.464844 12.53516,28 28,28 15.46484,0 28,-12.535156 28,-28 0,-15.464844 -12.53516,-28 -28,-28 -15.46484,0 -28,12.535156 -28,28 M 179.80078,20.199219 V 3.398438 m 0,16.800781 L 163,22.214844"
|
</g>
|
||||||
id="path35-4" />
|
<g id="use51" transform="matrix(1,0,0,1,154.672,160)">
|
||||||
<g
|
<path id="path20" d="M1.531,-7.922L1.531,-9C2.547,-9.098 3.254,-9.266 3.656,-9.496C4.059,-9.727 4.355,-10.277 4.555,-11.141L5.664,-11.141L5.664,0L4.164,0L4.164,-7.922L1.531,-7.922Z" style="fill-rule:nonzero;"/>
|
||||||
style="fill:#000000;fill-opacity:1"
|
</g>
|
||||||
id="g39">
|
</g>
|
||||||
<use
|
<path id="path55" d="M100,70L100,110" style="fill:none;fill-rule:nonzero;stroke:rgb(250,5,0);stroke-width:12px;stroke-linecap:butt;stroke-linejoin:bevel;"/>
|
||||||
xlink:href="#glyph0-2"
|
<path id="path57" d="M100,65L85,80L115,80L100,65" style="fill:rgb(250,5,0);fill-rule:nonzero;"/>
|
||||||
x="153"
|
|
||||||
y="47"
|
|
||||||
id="use37"
|
|
||||||
width="100%"
|
|
||||||
height="100%" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
|
||||||
d="m 11.807447,40 c 0,15.464844 12.535157,28 28.000001,28 15.464844,0 28,-12.535156 28,-28 0,-15.464844 -12.535156,-28 -28,-28 C 24.342604,12 11.807447,24.535156 11.807447,40 M 20.006667,20.199219 22.022292,37 M 20.006667,20.199219 H 3.2058824"
|
|
||||||
id="path41-0" />
|
|
||||||
<g
|
|
||||||
style="fill:#000000;fill-opacity:1"
|
|
||||||
id="g45">
|
|
||||||
<use
|
|
||||||
xlink:href="#glyph0-3"
|
|
||||||
x="33"
|
|
||||||
y="47"
|
|
||||||
id="use43"
|
|
||||||
width="100%"
|
|
||||||
height="100%" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
|
||||||
d="m 140,140 h 28 v 28 h -28 z m 0,0"
|
|
||||||
id="path47" />
|
|
||||||
<g
|
|
||||||
style="fill:#000000;fill-opacity:1"
|
|
||||||
id="g53">
|
|
||||||
<use
|
|
||||||
xlink:href="#glyph1-1"
|
|
||||||
x="144"
|
|
||||||
y="160"
|
|
||||||
id="use49"
|
|
||||||
width="100%"
|
|
||||||
height="100%" />
|
|
||||||
<use
|
|
||||||
xlink:href="#glyph1-2"
|
|
||||||
x="154.67188"
|
|
||||||
y="160"
|
|
||||||
id="use51"
|
|
||||||
width="100%"
|
|
||||||
height="100%" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
style="fill:none;stroke:#fa0500;stroke-width:12;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-opacity:1"
|
|
||||||
d="m 100,70 v 40"
|
|
||||||
id="path55" />
|
|
||||||
<path
|
|
||||||
style="fill:#fa0500;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
||||||
d="M 100,65 85,80 h 30 L 100,65"
|
|
||||||
id="path57" />
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 6.3 KiB |
1
resources/osd/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
/*.png
|
|
330
resources/osd/INAV Character Map.md
Normal file
|
@ -0,0 +1,330 @@
|
||||||
|
# Characters
|
||||||
|
|
||||||
|
| Preview | Firmware Variable | Configurator Variable | Description | Decimal ID | HEX ID |
|
||||||
|
|--------------------------------------------------------------------|----------------------------|------------------------------|---------------------------------------|------------|--------------|
|
||||||
|
|  | SYM_NONE | | Completely transparent icon | 000 | 0x00 |
|
||||||
|
|  | SYM_RSSI | SYM.RSSI | RSSI Icon | 001 | 0x01 |
|
||||||
|
|  | SYM_LQ | SYM.LQ | LQ Icon | 002 | 0x02 |
|
||||||
|
|  | SYM_LAT | SYM.LAT | Latitude | 003 | 0x03 |
|
||||||
|
|  | SYM_LON | SYM.LON | Longitude | 004 | 0x04 |
|
||||||
|
|  | SYM_AZIMUTH | SYM.AZIMUTH | Azimuth | 005 | 0x05 |
|
||||||
|
|  | SYM_TELEMETRY_0 | | Antenna tracking Telemetry | 006 | 0x06 |
|
||||||
|
|  | SYM_TELEMETRY_1 | | Antenna tracking Telemetry | 007 | 0x07 |
|
||||||
|
|  | SYM_SAT_L | SYM.GPS_SAT1 | Satellites Icon, left side | 008 | 0x08 |
|
||||||
|
| | SYM_SAT_R | SYM.GPS_SAT2 | Satellites Icon, right side | 009 | 0x09 |
|
||||||
|
|  | SYM_HOME_NEAR | | Icon shown at home point | 010 | 0x0A |
|
||||||
|
|  | SYM_DEGREES | SYM.DEGREES | Degree symbol | 011 | 0x0B |
|
||||||
|
|  | SYM_HEADING | SYM.HEADING | Heading symbol | 012 | 0x0C |
|
||||||
|
|  | SYM_SCALE | SYM.SCALE | Map scale symbol | 013 | 0x0D |
|
||||||
|
|  | SYM_HDP_L | SYM.GPS_HDP1 | HDOP icon, left side | 014 | 0x0E |
|
||||||
|
| | SYM_HDP_R | SYM.GPS_HDP2 | HDOP icon, right side | 015 | 0x0F |
|
||||||
|
|  | SYM_HOME | SYM.HOME | Home icon | 016 | 0x10 |
|
||||||
|
|  | SYM_2RSS | SYM.RSS2 | RSSI 2 icon | 017 | 0x11 |
|
||||||
|
|  | SYM_DB | SYM.DB | Decibel icon | 018 | 0x12 |
|
||||||
|
|  | SYM_DBM | SYM.DBM | Decibel per milliwatt icon | 019 | 0x13 |
|
||||||
|
|  | SYM_SNR | SYM.SNR | Signal to Noise Ratio icon | 020 | 0x14 |
|
||||||
|
|  | SYM_AH_DECORATION_UP | SYM.AH_DECORATION_UP | AHi up arrow | 021 | 0x15 |
|
||||||
|
|  | SYM_AH_DECORATION_DOWN | | AHI down arrow | 022 | 0x16 |
|
||||||
|
|  | SYM_DECORATION | SYM.DECORATION | Direction little arrows | 023 - 030 | 0x17 - 0x1E |
|
||||||
|
|  | | | | 024 | 0x18 |
|
||||||
|
|  | | | | 025 | 0x19 |
|
||||||
|
|  | | | | 026 | 0x1A |
|
||||||
|
|  | | | | 027 | 0x1B |
|
||||||
|
|  | | | | 028 | 0x1C |
|
||||||
|
|  | | | | 029 | 0x1D |
|
||||||
|
|  | | | | 030 | 0x1E |
|
||||||
|
|  | SYM_VOLT | SYM.VOLT | Volts symbol | 031 | 0x1F |
|
||||||
|
|  | SYM_BLANK _*_ | SYM.BLANK | Empty | 032 | 0x20 |
|
||||||
|
|  | _ASCII_ _*_ | | ! | 033 | 0x21 |
|
||||||
|
|  | SYM_AH_KM | | Ah per Km | 034 | 0x22 |
|
||||||
|
|  | _ASCII_ _*_ | | # | 035 | 0x23 |
|
||||||
|
|  | SYM_AH_MI | | Ah per Mile | 036 | 0x24 |
|
||||||
|
|  | _ASCII_ _*_ | | % | 037 | 0x25 |
|
||||||
|
|  | _ASCII_ _*_ | | & | 038 | 0x26 |
|
||||||
|
|  | SYM_VTX_POWER | SYM.VTX_POWER | VTx Power | 039 | 0x27 |
|
||||||
|
|  | _ASCII_ _*_ | | Symbols and numbers | 040 - 062 | 0x28 - 0x3E |
|
||||||
|
|  | _ASCII_ _*_ | | | 041 | 0x29 |
|
||||||
|
|  | _ASCII_ _*_ | | | 042 | 0x2A |
|
||||||
|
|  | _ASCII_ _*_ | | | 043 | 0x2B |
|
||||||
|
|  | _ASCII_ _*_ | | | 044 | 0x2C |
|
||||||
|
|  | _ASCII_ _*_ | | | 045 | 0x2D |
|
||||||
|
|  | _ASCII_ _*_ | | | 046 | 0x2E |
|
||||||
|
|  | _ASCII_ _*_ | | | 047 | 0x2F |
|
||||||
|
|  | _ASCII_ _*_ | | | 048 | 0x30 |
|
||||||
|
|  | _ASCII_ _*_ | | | 049 | 0x31 |
|
||||||
|
|  | _ASCII_ _*_ | | | 050 | 0x32 |
|
||||||
|
|  | _ASCII_ _*_ | | | 051 | 0x33 |
|
||||||
|
|  | _ASCII_ _*_ | | | 052 | 0x34 |
|
||||||
|
|  | _ASCII_ _*_ | | | 053 | 0x35 |
|
||||||
|
|  | _ASCII_ _*_ | | | 054 | 0x36 |
|
||||||
|
|  | _ASCII_ _*_ | | | 055 | 0x37 |
|
||||||
|
|  | _ASCII_ _*_ | | | 056 | 0x38 |
|
||||||
|
|  | _ASCII_ _*_ | | | 057 | 0x39 |
|
||||||
|
|  | _ASCII_ _*_ | | | 058 | 0x3A |
|
||||||
|
|  | _ASCII_ _*_ | | | 059 | 0x3B |
|
||||||
|
|  | _ASCII_ _*_ | | | 060 | 0x3C |
|
||||||
|
|  | _ASCII_ _*_ | | | 061 | 0x3D |
|
||||||
|
|  | _ASCII_ _*_ | | | 062 | 0x3E |
|
||||||
|
|  | SYM_AH_NM | SYM.AH_NM | Ah per Nautical Mile | 063 | 0x3F |
|
||||||
|
|  | _ASCII_ _*_ | | Alphabet and symbols | 064 - 095 | 0x40 - 0x5F |
|
||||||
|
|  | _ASCII_ _*_ | | | 065 | 0x41 |
|
||||||
|
|  | _ASCII_ _*_ | | | 066 | 0x42 |
|
||||||
|
|  | _ASCII_ _*_ | | | 067 | 0x43 |
|
||||||
|
|  | _ASCII_ _*_ | | | 068 | 0x44 |
|
||||||
|
|  | _ASCII_ _*_ | | | 069 | 0x45 |
|
||||||
|
|  | _ASCII_ _*_ | | | 070 | 0x46 |
|
||||||
|
|  | _ASCII_ _*_ | | | 071 | 0x47 |
|
||||||
|
|  | _ASCII_ _*_ | | | 072 | 0x48 |
|
||||||
|
|  | _ASCII_ _*_ | | | 073 | 0x49 |
|
||||||
|
|  | _ASCII_ _*_ | | | 074 | 0x4A |
|
||||||
|
|  | _ASCII_ _*_ | | | 075 | 0x4B |
|
||||||
|
|  | _ASCII_ _*_ | | | 076 | 0x4C |
|
||||||
|
|  | _ASCII_ _*_ | | | 077 | 0x4D |
|
||||||
|
|  | _ASCII_ _*_ | | | 078 | 0x4E |
|
||||||
|
|  | _ASCII_ _*_ | | | 079 | 0x4F |
|
||||||
|
|  | _ASCII_ _*_ | | | 080 | 0x50 |
|
||||||
|
|  | _ASCII_ _*_ | | | 081 | 0x51 |
|
||||||
|
|  | _ASCII_ _*_ | | | 082 | 0x52 |
|
||||||
|
|  | _ASCII_ _*_ | | | 083 | 0x53 |
|
||||||
|
|  | _ASCII_ _*_ | | | 084 | 0x54 |
|
||||||
|
|  | _ASCII_ _*_ | | | 085 | 0x55 |
|
||||||
|
|  | _ASCII_ _*_ | | | 086 | 0x56 |
|
||||||
|
|  | _ASCII_ _*_ | | | 087 | 0x57 |
|
||||||
|
|  | _ASCII_ _*_ | | | 088 | 0x58 |
|
||||||
|
|  | _ASCII_ _*_ | | | 089 | 0x59 |
|
||||||
|
|  | _ASCII_ _*_ | | | 090 | 0x5A |
|
||||||
|
|  | _ASCII_ _*_ | | | 091 | 0x5B |
|
||||||
|
|  | _ASCII_ _*_ | | | 092 | 0x5C |
|
||||||
|
|  | _ASCII_ _*_ | | | 093 | 0x5D |
|
||||||
|
|  | _ASCII_ _*_ | | | 094 | 0x5E |
|
||||||
|
|  | _ASCII_ _*_ | | | 095 | 0x5F |
|
||||||
|
|  | SYM_MAH_NM_0 | SYM.MAH_NM_0 | mAh per Nautical mile, left side | 096 | 0x60 |
|
||||||
|
| | SYM_MAH_NM_1 | SYM.MAH_NM_1 | mAh per Nautical mile, right side | 097 | 0x61 |
|
||||||
|
|  | SYM_MILLIOHM | SYM.MILLIOHM | MilliOhm symbol | 098 | 0x62 |
|
||||||
|
|  | SYM_BATT_FULL | SYM.BATT | Battery full | 099 | 0x63 |
|
||||||
|
|  | SYM_BATT_5 | | Battery ~83% | 100 | 0x64 |
|
||||||
|
|  | SYM_BATT_4 | | Battery ~67% | 101 | 0x65 |
|
||||||
|
|  | SYM_BATT_3 | | Battery ~50% | 102 | 0x66 |
|
||||||
|
|  | SYM_BATT_2 | | Battery ~34% | 103 | 0x67 |
|
||||||
|
|  | SYM_BATT_1 | | Battery ~17% | 104 | 0x68 |
|
||||||
|
|  | SYM_BATT_EMPTY | | Battery EMPTY | 105 | 0x69 |
|
||||||
|
|  | SYM_AMP | SYM.AMP | Amps symbol | 106 | 0x6A |
|
||||||
|
|  | SYM_MAH_KM_0 | SYM.MAH_KM_0 | mAh per Kilometre, left side | 107 | 0x6B |
|
||||||
|
| | SYM_MAH_KM_1 | SYM.MAH_KM_1 | mAh per Kilometre, right side | 108 | 0x6C |
|
||||||
|
|  | SYM_WH | SYM.WH | Watthours symbol | 109 | 0x6D |
|
||||||
|
|  | SYM_WH_KM | SYM.WH_KM | Watthours per Kilometre | 110 | 0x6E |
|
||||||
|
|  | SYM_WH_MI | SYM.WH_MI | Watthours per Mile | 111 | 0x6F |
|
||||||
|
|  | SYM_WH_NM | SYM.WH_NM | Watthours per Nautical Mile | 112 | 0x70 |
|
||||||
|
|  | SYM_WATT | SYM.WATT | Watts symbol | 113 | 0x71 |
|
||||||
|
|  | SYM_MW | SYM.MW | Milliwatts symbol | 114 | 0x72 |
|
||||||
|
|  | SYM_KILOWATT | | Kilowatts symbol | 115 | 0x73 |
|
||||||
|
|  | SYM_FT | | Feet symbol | 116 | 0x74 |
|
||||||
|
|  | SYM_TRIP_DIST | SYM.TRIP_DIST | Trip distance | 117 | 0x75 |
|
||||||
|
|  | SYM_TOTAL | | Total distance | 117 | 0x75 |
|
||||||
|
|  | SYM_ALT_M | SYM.ALT_M | Alitiude in Metres | 118 | 0x76 |
|
||||||
|
|  | SYM_ALT_KM | | Altitude in Kilometres | 119 | 0x77 |
|
||||||
|
|  | SYM_ALT_FT | SYM.ALT_FT | Altitude in Feet | 120 | 0x78 |
|
||||||
|
|  | SYM_ALT_KFT | | Altitude in thousand Feet | 121 | 0x79 |
|
||||||
|
|  | SYM_DIST_M | | Distance in Metres | 122 | 0x7A |
|
||||||
|
|  | _ASCII_ _*_ | | Bracket symbols | 123 - 125 | 0x7B - 0x7D |
|
||||||
|
|  | _ASCII_ _*_ | | | 124 | 0x7C |
|
||||||
|
|  | _ASCII_ _*_ | | | 125 | 0x7D |
|
||||||
|
|  | SYM_DIST_KM | SYM.DIST_KM | Distance in Kilometres | 126 | 0x7E |
|
||||||
|
|  | SYM_DIST_FT | | Distance in Feet | 127 | 0x7F |
|
||||||
|
|  | SYM_DIST_MI | SYM.DIST_MI | Distance in Miles | 128 | 0x80 |
|
||||||
|
|  | SYM_DIST_NM | SYM.DIST_NM | Distance in Nautical Miles | 129 | 0x81 |
|
||||||
|
|  | SYM_M | SYM.M | Metres symbol | 130 | 0x82 |
|
||||||
|
|  | SYM_KM | | Kilometres symbol | 131 | 0x83 |
|
||||||
|
|  | SYM_MI | SYM.MI | Miles symbol | 132 | 0x84 |
|
||||||
|
|  | SYM_NM | SYM.NM | Nautical Miles symbol | 133 | 0x85 |
|
||||||
|
|  | SYM_WIND_HORIZONTAL | SYM.WIND_SPEED_HORIZONTAL | Horizontal wind speed | 134 | 0x86 |
|
||||||
|
|  | SYM_WIND_VERTICAL | SYM.WIND_SPEED_VERITCAL | Vertical wind speed | 135 | 0x87 |
|
||||||
|
|  | SYM_3D_KMH | SYM.KMH_3D | 3D speed in Kilometres per Hour | 136 | 0x88 |
|
||||||
|
|  | SYM_3D_MPH | SYM.MPH_3D | 3D speed in Miles per Hour | 137 | 0x89 |
|
||||||
|
|  | SYM_3D_KT | SYM.KT_3D | 3D speed in Knots | 138 | 0x8A |
|
||||||
|
|  | SYM_RPM | SYM.RPM | Revolutions per Minute symbol | 139 | 0x8B |
|
||||||
|
|  | SYM_AIR | SYM.AIR | Air: Prefix for airspeed sensor | 140 | 0x8C |
|
||||||
|
|  | SYM_FTS | SYM.FT_S | Feet per Second | 141 | 0x8D |
|
||||||
|
|  | SYM_100FTM | SYM.HUND_FTM | 100 Feet per Minute | 142 | 0x8E |
|
||||||
|
|  | SYM_MS | SYM.M_S | Metres per Second | 143 | 0x8F |
|
||||||
|
|  | SYM_KMH | SYM.KMH | Kilometres per Hour | 144 | 0x90 |
|
||||||
|
|  | SYM_MPH | SYM.MPH | Miles per Hour | 145 | 0x91 |
|
||||||
|
|  | SYM_KT | SYM.KT | Knots | 146 | 0x92 |
|
||||||
|
|  | SYM_MAH_MI_0 | SYM.MAH_MI_0 | mAh per Mile, left side | 147 | 0x93 |
|
||||||
|
| | SYM_MAH_MI_1 | SYM.MAH_MI_1 | mAh per Mile, right side | 148 | 0x94 |
|
||||||
|
|  | SYM_THR | SYM.THR | Throttle symbol | 149 | 0x95 |
|
||||||
|
|  | SYM_TEMP_F | SYM.TEMP_F | Fahrenheit symbol | 150 | 0x96 |
|
||||||
|
|  | SYM_TEMP_C | SYM.TEMP_C | Celsius symbol | 151 | 0x97 |
|
||||||
|
|  | _reserved or old ?_ | | Home point map | 152 | 0x98 |
|
||||||
|
|  | SYM_MAH | SYM.MAH | mAh sysmbol | 153 | 0x99 |
|
||||||
|
|  | SYM_ON_H | | On hours | 154 | 0x9A |
|
||||||
|
|  | SYM_FLY_H | | Flying hours | 155 | 0x9B |
|
||||||
|
|  | SYM_GLIDESLOPE | SYM.GLIDESLOPE | Glide slope | 156 | 0x9C |
|
||||||
|
|  | SYM_WAYPOINT | | Waypoint | 157 | 0x9D |
|
||||||
|
|  | SYM_ON_M | SYM.ON_M | On minutes | 158 | 0x9E |
|
||||||
|
|  | SYM_FLY_M | SYM.FLY_M | Flying minutes | 159 | 0x9F |
|
||||||
|
|  | SYM_CLOCK | SYM.CLOCK | Clock | 160 | 0xA0 |
|
||||||
|
|  | SYM_ZERO_HALF_TRAILING_DOT | SYM.ZERO_HALF_TRAILING_DOT | Numbers with trailing dots | 161 - 170 | 0xA1 - 0xAA |
|
||||||
|
|  | | | | 162 | 0xA2 |
|
||||||
|
|  | | | | 163 | 0xA3 |
|
||||||
|
|  | | | | 164 | 0xA4 |
|
||||||
|
|  | | | | 165 | 0xA5 |
|
||||||
|
|  | | | | 166 | 0xA6 |
|
||||||
|
|  | | | | 167 | 0xA7 |
|
||||||
|
|  | | | | 168 | 0xA8 |
|
||||||
|
|  | | | | 169 | 0xA9 |
|
||||||
|
|  | | | | 170 | 0xAA |
|
||||||
|
|  | SYM_AUTO_THR0 | | Auto-throttle symbol, left side | 171 | 0xAB |
|
||||||
|
| | SYM_AUTO_THR1 | | Auto-throttle symbol, right side | 172 | 0xAC |
|
||||||
|
|  | SYM_ROLL_LEFT | SYM.ROLL_LEFT | roll left symbol | 173 | 0xAD |
|
||||||
|
|  | SYM_ROLL_LEVEL | SYM.ROLL_LEVEL | roll level symbol | 174 | 0xAE |
|
||||||
|
|  | SYM_ROLL_RIGHT | SYM.ROLL_RIGHT | roll right symbol | 175 | 0xAF |
|
||||||
|
|  | SYM_PITCH_UP | SYM.PITCH_UP | Pitch up symbol | 176 | 0xB0 |
|
||||||
|
|  | SYM_ZERO_HALF_LEADING_DOT | SYM.ZERO_HALF_LEADING_DOT | Numbers with leading dots | 177 - 186 | 0xB1 - 0xBA |
|
||||||
|
|  | | | | 178 | 0xB2 |
|
||||||
|
|  | | | | 179 | 0xB3 |
|
||||||
|
|  | | | | 180 | 0xB4 |
|
||||||
|
|  | | | | 181 | 0xB5 |
|
||||||
|
|  | | | | 182 | 0xB6 |
|
||||||
|
|  | | | | 183 | 0xB7 |
|
||||||
|
|  | | | | 184 | 0xB8 |
|
||||||
|
|  | | | | 185 | 0xB9 |
|
||||||
|
|  | | | | 186 | 0xBA |
|
||||||
|
|  | SYM_PITCH_DOWN | SYM.PITCH_DOWN | Pitch down symbol | 187 | 0xBB |
|
||||||
|
|  | SYM_GFORCE | SYM.GFORCE | Gforce (all axis) | 188 | 0xBC |
|
||||||
|
|  | SYM_GFORCE_X | SYM.GFORCE_X | Gforce X | 189 | 0xBD |
|
||||||
|
|  | SYM_GFORCE_Y | SYM.GFORCE_Y | Gforce Y | 190 | 0xBE |
|
||||||
|
|  | SYM_GFORCE_Z | SYM.GFORCE_Z | Gforce Z | 191 | 0xBF |
|
||||||
|
|  | SYM_BARO_TEMP | SYM.BARO_TEMP | Barometer temperature | 192 | 0xC0 |
|
||||||
|
|  | SYM_IMU_TEMP | SYM.IMU_TEMP | IMU temperature | 193 | 0xC1 |
|
||||||
|
|  | SYM_TEMP | SYM.TEMP | Thermometer symbol **First symbol** | 194 | 0xC2 |
|
||||||
|
|  | SYM_ESC_TEMP | SYM.ESC_TEMPERATURE | ESC temperature | 195 | 0xC3 |
|
||||||
|
|  | | | | 196 | 0xC4 |
|
||||||
|
|  | | | | 197 | 0xC5 |
|
||||||
|
|  | | | | 198 | 0xC6 |
|
||||||
|
|  | | | | 199 | 0xC7 |
|
||||||
|
|  | SYM_HEADING_N | SYM.HEADING_N | Heading graph North | 200 | 0xC8 |
|
||||||
|
|  | SYM_HEADING_S | SYM.HEADING_S | Heading graph South | 201 | 0xC9 |
|
||||||
|
|  | SYM_HEADING_E | SYM.HEADING_E | Heading graph East | 202 | 0xCA |
|
||||||
|
|  | SYM_HEADING_W | SYM.HEADING_W | Heading graph West | 203 | 0xCB |
|
||||||
|
|  | SYM_HEADING_DIVIDED_LINE | SYM.HEADING_DIVIDED_LINE | Heading graphic | 204 | 0xCC |
|
||||||
|
|  | SYM_HEADING_LINE | SYM.HEADING_LINE | Heading graphic | 205 | 0xCD |
|
||||||
|
|  | SYM_MAX | SYM.MAX | Max icon | 206 | 0xCE |
|
||||||
|
|  | SYM_PROFILE | SYM.PROFILE | Profile icon | 207 | 0xCF |
|
||||||
|
|  | SYM_SWITCH_INDICATOR_LOW | N/A | Switch: down | 208 | 0xD0 |
|
||||||
|
|  | SYM_SWITCH_INDICATOR_LOW | N/A | Switch: middle | 209 | 0xD1 |
|
||||||
|
|  | SYM_SWITCH_INDICATOR_LOW | SYM.SWITCH_INDICATOR_HIGH | Switch: up | 210 | 0xD2 |
|
||||||
|
|  | SYM_AH | SYM.AHI | Amp Hours icon | 211 | 0xD3 |
|
||||||
|
|  | SYM_GLIDE_DIST | SYM.GLIDE_DIST | Glide Distance | 212 | 0xD4 |
|
||||||
|
|  | SYM_GLIDE_MINS | SYM.GLIDE_MINS | Glide Time Mins | 213 | 0xD5 |
|
||||||
|
|  | SYM_AH_V_FT_0 | SYM.AH_V_FT_0 | Climb efficiency: imperial L side | 214 | 0xD6 |
|
||||||
|
| | SYM_AH_V_FT_1 | SYM.AH_V_FT_1 | Climb efficiency: imperial R side | 215 | 0xD7 |
|
||||||
|
|  | SYM_AH_V_M_0 | SYM.AH_V_M_0 | Climb efficiency: metric L side | 216 | 0xD8 |
|
||||||
|
| | SYM_AH_V_M_1 | SYM.AH_V_M_1 | Climb efficiency: metric R side | 217 | 0xD9 |
|
||||||
|
|  | SYM_FLIGHT_MINS_REMAINING | SYM.FLIGHT_MINS_REMAINING | Flight time (mins) remaining | 218 | 0xDA |
|
||||||
|
|  | SYM_FLIGHT_HOURS_REMAINING | | Flight time (hours) remaining | 219 | 0xDB |
|
||||||
|
|  | SYM_GROUND_COURSE | SYM.GROUND_COURSE | Ground course | 220 | 0xDC |
|
||||||
|
|  | SYM_ALERT | SYM.ALERT | General Alert | 221 | 0xDD |
|
||||||
|
|  | SYM_TERRAIN_FOLLOWING | SYM.TERRAIN_FOLLOWING | Terrain following | 251 | 0xFB |
|
||||||
|
|  | SYM_CROSS_TRACK_ERROR | SYM.CROSS_TRACK_ERROR | Cross track error | 252 | 0xFC |
|
||||||
|
|  | SYM_ADSB | SYM.ADSB | ADSB | 253 | 0xFD |
|
||||||
|
|  | SYM_BLACKBOX | SYM.BLACKBOX | Blackbox | 254 | 0xFE |
|
||||||
|
| | | | | | |
|
||||||
|
|  | SYM_LOGO_START | | INAV Logo | 257 - 296 | 0x101 - 0x128 |
|
||||||
|
|  | SYM_AH_LEFT | SYM.AH_LEFT | AHI Arrow left | 300 | 0x12C |
|
||||||
|
|  | SYM_AH_RIGHT | SYM.AH_RIGHT | AHI Arrow right | 301 | 0x12D |
|
||||||
|
|  | SYM_AH_DECORATION_MIN | | AHI Scrolling graphics | 302 - 307 | 0x12E - 0x133 |
|
||||||
|
|  | | | | 303 | 0x12F |
|
||||||
|
|  | | | | 304 | 0x130 |
|
||||||
|
|  | SYM_AH_DECORATION | SYM.AH_DECORATION | AHI Scrolling graphics | 305 | 0x131 |
|
||||||
|
|  | | | | 306 | 0x132 |
|
||||||
|
|  | SYM_AH_DECORATION_MAX | | AHI Scrolling graphics | 307 | 0x133 |
|
||||||
|
|  | SYM_AH_CH_LEFT | SYM.AH_CENTER_LINE | Crosshair left | 314 | 0x13A |
|
||||||
|
|  | SYM_AH_CH_RIGHT | SYM.AH_CENTER_LINE_RIGHT | Crosshair right | 315 | 0x13B |
|
||||||
|
|  | SYM_ARROW_UP | SYM.DIR_TO_HOME | Direction arrow 0° | 316 | 0x13C |
|
||||||
|
|  | SYM_ARROW_2 | | Direction arrow 22.5° | 317 | 0x13D |
|
||||||
|
|  | SYM_ARROW_3 | | Direction arrow 45° | 318 | 0x13E |
|
||||||
|
|  | SYM_ARROW_4 | | Direction arrow 67.5° | 319 | 0x13F |
|
||||||
|
|  | SYM_ARROW_RIGHT | | Direction arrow 90° | 320 | 0x140 |
|
||||||
|
|  | SYM_ARROW_6 | | Direction arrow 112.5° | 321 | 0x141 |
|
||||||
|
|  | SYM_ARROW_7 | | Direction arrow 135° | 322 | 0x142 |
|
||||||
|
|  | SYM_ARROW_8 | | Direction arrow 157.5° | 323 | 0x143 |
|
||||||
|
|  | SYM_ARROW_DOWN | | Direction arrow 180° | 324 | 0x144 |
|
||||||
|
|  | SYM_ARROW_10 | | Direction arrow 202.5° | 325 | 0x145 |
|
||||||
|
|  | SYM_ARROW_11 | | Direction arrow 225° | 326 | 0x146 |
|
||||||
|
|  | SYM_ARROW_12 | | Direction arrow 247.5° | 327 | 0x147 |
|
||||||
|
|  | SYM_ARROW_LEFT | | Direction arrow 270° | 328 | 0x148 |
|
||||||
|
|  | SYM_ARROW_14 | | Direction arrow 292.5° | 329 | 0x149 |
|
||||||
|
|  | SYM_ARROW_15 | | Direction arrow 315° | 330 | 0x14A |
|
||||||
|
|  | SYM_ARROW_16 | | Direction arrow 337.5° | 331 | 0x14B |
|
||||||
|
|  | SYM_AH_H_START | SYM.AH_BAR9_0 | Horizontal AHI | 332 - 340 | 0x14C - 0x154 |
|
||||||
|
|  | | | Horizontal AHI | 333 | 0x14D |
|
||||||
|
|  | | | Horizontal AHI | 334 | 0x14E |
|
||||||
|
|  | | | Horizontal AHI | 335 | 0x14F |
|
||||||
|
|  | | | Horizontal AHI | 336 | 0x150 |
|
||||||
|
|  | | | Horizontal AHI | 337 | 0x151 |
|
||||||
|
|  | | | Horizontal AHI | 338 | 0x152 |
|
||||||
|
|  | | | Horizontal AHI | 339 | 0x153 |
|
||||||
|
|  | | | Horizontal AHI | 340 | 0x154 |
|
||||||
|
|  | SYM_VARIO_UP_2A | SYM.VARIO_UP_2A | Vario up up | 341 | 0x155 |
|
||||||
|
|  | SYM_VARIO_UP_1A | | Vario up | 342 | 0x156 |
|
||||||
|
|  | SYM_VARIO_DOWN_1A | | Vario down | 343 | 0x157 |
|
||||||
|
|  | SYM_VARIO_DOWN_2A | | Vario down down | 344 | 0x158 |
|
||||||
|
|  | SYM_ALT | | Altitude symbol | 345 | 0x159 |
|
||||||
|
|  | SYM_AH_V_START | | Vertical AHI | 346 - 351 | 0x15A - 0x159 |
|
||||||
|
|  | | | | 347 | 0x15B |
|
||||||
|
|  | | | | 348 | 0x15C |
|
||||||
|
|  | | | | 349 | 0x15D |
|
||||||
|
|  | | | | 350 | 0x15E |
|
||||||
|
|  | | | | 351 | 0x15F |
|
||||||
|
|  | SYM_HUD_SIGNAL_0 | | HUD signal lost icon | 352 | 0x160 |
|
||||||
|
|  | SYM_HUD_SIGNAL_1 | | HUD signal 25% icon | 353 | 0x161 |
|
||||||
|
|  | SYM_HUD_SIGNAL_2 | | HUD signal 50% icon | 354 | 0x162 |
|
||||||
|
|  | SYM_HUD_SIGNAL_3 | | HUD signal 75% icon | 355 | 0x163 |
|
||||||
|
|  | SYM_HUD_SIGNAL_4 | | HUD signal 100% icon | 356 | 0x164 |
|
||||||
|
|  | SYM_HOME_DIST | | Home distance icon | 357 | 0x165 |
|
||||||
|
|  | SYM_AH_CH_CENTER | SYM.AH_CROSSHAIRS | Default crosshair centre | 358 | 0x166 |
|
||||||
|
|  | SYM_FLIGHT_DIST_REMAINING | SYM.FLIGHT_DIST_REMAINING | Flight distance remaining | 359 | 0x167 |
|
||||||
|
|  | SYM_ODOMETER | SYM.ODOMETER | Odometer (total aircraft distance) | 360 | 0x168 |
|
||||||
|
|  | SYM_AH_CH_TYPE3 | SYM.AH_CROSSHAIRS | Crosshair type 3 | 400 - 402 | 0x190 - 0x192 |
|
||||||
|
|  | SYM_AH_CH_TYPE4 | SYM.AH_CROSSHAIRS | Crosshair type 4 | 403 - 405 | 0x193 - 0x195 |
|
||||||
|
|  | SYM_AH_CH_TYPE5 | SYM.AH_CROSSHAIRS | Crosshair type 5 | 406 - 408 | 0x196 - 0x198 |
|
||||||
|
|  | SYM_AH_CH_TYPE6 | SYM.AH_CROSSHAIRS | Crosshair type 6 | 409 - 411 | 0x199 - 0x19B |
|
||||||
|
|  | SYM_AH_CH_TYPE7 | SYM.AH_CROSSHAIRS | Crosshair type 7 | 412 - 414 | 0x19C - 0x19E |
|
||||||
|
|  | SYM_AH_CH_TYPE8 | SYM.AH_CROSSHAIRS | Crosshair type 8 | 415 - 417 | 0x19F - 0x1A1 |
|
||||||
|
|  | SYM_AH_CH_AIRCRAFT0 | SYM.AH_AIRCRAFT0 | Aircraft crosshair left | 418 | 0x1A2 |
|
||||||
|
| | SYM_AH_CH_AIRCRAFT1 | SYM.AH_AIRCRAFT1 | Aircraft crosshair | 419 | 0x1A3 |
|
||||||
|
| | SYM_AH_CH_AIRCRAFT2 | SYM.AH_AIRCRAFT2 | Aircraft crosshair centre | 420 | 0x1A4 |
|
||||||
|
| | SYM_AH_CH_AIRCRAFT3 | SYM.AH_AIRCRAFT3 | Aircraft crosshair | 421 | 0x1A5 |
|
||||||
|
| | SYM_AH_CH_AIRCRAFT4 | SYM.AH_AIRCRAFT4 | Aircraft crosshair right | 422 | 0x1A6 |
|
||||||
|
|  | SYM_HUD_ARROWS_L1 | | 1 arrow left | 430 | 0x1AE |
|
||||||
|
|  | SYM_HUD_ARROWS_L2 | | 2 arrows left | 431 | 0x1AF |
|
||||||
|
|  | SYM_HUD_ARROWS_L3 | | 3 arrows left | 432 | 0x1B0 |
|
||||||
|
|  | SYM_HUD_ARROWS_R1 | | 1 arrow right | 433 | 0x1B1 |
|
||||||
|
|  | SYM_HUD_ARROWS_R2 | | 2 arrows right | 434 | 0x1B2 |
|
||||||
|
|  | SYM_HUD_ARROWS_R3 | | 3 arrows right | 435 | 0x1B3 |
|
||||||
|
|  | SYM_HUD_ARROWS_U1 | | 1 arrow up | 436 | 0x1B4 |
|
||||||
|
|  | SYM_HUD_ARROWS_U2 | | 2 arrows up | 437 | 0x1B5 |
|
||||||
|
|  | SYM_HUD_ARROWS_U3 | | 3 arrows up | 438 | 0x1B6 |
|
||||||
|
|  | SYM_HUD_ARROWS_D1 | | 1 arrow down | 439 | 0x1B7 |
|
||||||
|
|  | SYM_HUD_ARROWS_D2 | | 2 arrows down | 440 | 0x1B8 |
|
||||||
|
|  | SYM_HUD_ARROWS_D3 | | 3 arrows down | 441 | 0x1B9 |
|
||||||
|
|  | SYM_HUD_CARDINAL | | Cardinal indicators | 442 - 453 | 0x1BA - 0x1C5 |
|
||||||
|
|  | | | | 443 | 0x1BB |
|
||||||
|
|  | | | | 444 | 0x1BC |
|
||||||
|
|  | | | | 445 | 0x1BD |
|
||||||
|
|  | | | | 446 | 0x1BE |
|
||||||
|
|  | | | | 447 | 0x1BF |
|
||||||
|
|  | | | | 448 | 0x1C0 |
|
||||||
|
|  | | | | 449 | 0x1C1 |
|
||||||
|
|  | | | | 450 | 0x1C2 |
|
||||||
|
|  | | | | 451 | 0x1C3 |
|
||||||
|
|  | | | | 452 | 0x1C4 |
|
||||||
|
|  | | | | 453 | 0x1C5 |
|
||||||
|
|  | SYM_SERVO_PAN_IS_CENTRED | | Pan servo is centred | 454 | 0x1C6 |
|
||||||
|
|  | SYM_SERVO_PAN_IS_OFFSET_L | SYM.PAN_SERVO_IS_OFFSET_L | Pan servo is moved to the left | 455 | 0x1C7 |
|
||||||
|
|  | SYM_SERVO_PAN_IS_OFFSET_R | | Pan servo is moved to the right | 456 | 0x1C8 |
|
||||||
|
|  | SYM_PILOT_LOGO_SML_L | SYM.PILOT_LOGO_SML_L | Small Pilot logo | 469 - 471 | 0x1D5 - 0x1D7 |
|
||||||
|
|  | SYM_PILOT_LOGO_LRG_START | | Large Pilot logo | 472 - 511 | 0x1D5 - 0x1D7 |
|
||||||
|
|
||||||
|
_*_ Do not change the IDs of these characters
|
|
@ -3,7 +3,10 @@
|
||||||
This directory contains one directory per font. In each
|
This directory contains one directory per font. In each
|
||||||
directory, each character is named `%d%d%d.png`, where
|
directory, each character is named `%d%d%d.png`, where
|
||||||
the digits represent the decimal character number found
|
the digits represent the decimal character number found
|
||||||
in the filename without the extension.
|
in the filename without the extension. All characters
|
||||||
|
must be in the `default` font directory. If characters
|
||||||
|
missing from alternate font directories, the default
|
||||||
|
version of the character will be used.
|
||||||
|
|
||||||
Don't alter the `.mcm` files directly, those should be
|
Don't alter the `.mcm` files directly, those should be
|
||||||
only modified by altering the `.png` files found in its
|
only modified by altering the `.png` files found in its
|
BIN
resources/osd/analogue/bold.png
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 216 B After Width: | Height: | Size: 216 B |
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 238 B |
Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 230 B |
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 239 B |
Before Width: | Height: | Size: 180 B After Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 160 B After Width: | Height: | Size: 160 B |
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 452 B |
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 242 B |
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 324 B |
Before Width: | Height: | Size: 272 B After Width: | Height: | Size: 272 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 234 B |
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 255 B |
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 250 B |
Before Width: | Height: | Size: 259 B After Width: | Height: | Size: 259 B |