mirror of
https://github.com/iNavFlight/inav-configurator.git
synced 2025-07-24 00:35:20 +03:00
Merge branch 'master' into dzikuvx-simplify-receiver-tab
This commit is contained in:
commit
09a3a0b7df
59 changed files with 527 additions and 536 deletions
185
.github/workflows/ci.yml
vendored
Normal file
185
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
name: Build Configurator
|
||||||
|
# Don't enable CI on push, just on PR. If you
|
||||||
|
# are working on the main repo and want to trigger
|
||||||
|
# a CI build submit a draft PR.
|
||||||
|
on: pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup environment
|
||||||
|
env:
|
||||||
|
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||||
|
run: |
|
||||||
|
# This is the hash of the commit for the PR
|
||||||
|
# when the action is triggered by PR, empty otherwise
|
||||||
|
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||||
|
# This is the hash of the commit when triggered by push
|
||||||
|
# but the hash of refs/pull/<n>/merge, which is different
|
||||||
|
# from the hash of the latest commit in the PR, that's
|
||||||
|
# why we try github.event.pull_request.head.sha first
|
||||||
|
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||||
|
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||||
|
VERSION=$(grep version package.json | sed 's/.*"\([0-9][0-9]*.[0-9]*.[0-9]*\)".*/\1/g')
|
||||||
|
echo "ACTIONS_STEP_DEBUG=true" >> $GITHUB_ENV
|
||||||
|
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||||
|
echo "BUILD_NAME=inav-configurator_linux_x64_${VERSION}_${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
check-latest: true
|
||||||
|
cache: 'npm'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: sudo apt-get update && sudo apt-get -y install dpkg fakeroot rpm build-essential libudev-dev
|
||||||
|
- name: Install deps
|
||||||
|
uses: nick-fields/retry@v2
|
||||||
|
with:
|
||||||
|
max_attempts: 3
|
||||||
|
retry_on: error
|
||||||
|
command: npm install
|
||||||
|
timeout_minutes: 10
|
||||||
|
- name: Build Linux
|
||||||
|
run: npm run make
|
||||||
|
- name: Upload Linux deb
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.BUILD_NAME }}_DEB
|
||||||
|
path: ./out/make/deb/x64/*.deb
|
||||||
|
- name: Upload Linux rpm
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.BUILD_NAME }}_RPM
|
||||||
|
path: ./out/make/rpm/x64/*.rpm
|
||||||
|
- name: Upload Linux zip
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.BUILD_NAME }}_ZIP
|
||||||
|
path: ./out/make/zip/linux/x64/*.zip
|
||||||
|
build-mac:
|
||||||
|
runs-on: macos-13
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup environment
|
||||||
|
env:
|
||||||
|
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||||
|
run: |
|
||||||
|
# This is the hash of the commit for the PR
|
||||||
|
# when the action is triggered by PR, empty otherwise
|
||||||
|
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||||
|
# This is the hash of the commit when triggered by push
|
||||||
|
# but the hash of refs/pull/<n>/merge, which is different
|
||||||
|
# from the hash of the latest commit in the PR, that's
|
||||||
|
# why we try github.event.pull_request.head.sha first
|
||||||
|
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||||
|
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||||
|
VERSION=$(grep version package.json | sed 's/.*"\([0-9][0-9]*.[0-9]*.[0-9]*\)".*/\1/g')
|
||||||
|
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||||
|
echo "BUILD_NAMEx64=inav-configurator_darwin_x64_${VERSION}_${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||||
|
echo "BUILD_NAMEarm64=inav-configurator_darwin_arm64_${VERSION}_${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
check-latest: true
|
||||||
|
cache: 'npm'
|
||||||
|
# Workaround due to a bug in node-gyp: https://github.com/electron/rebuild/issues/1116
|
||||||
|
- name: Install Setuptools
|
||||||
|
run: python3 -m pip install --break-system-packages setuptools
|
||||||
|
- name: Install deps
|
||||||
|
uses: nick-fields/retry@v2
|
||||||
|
with:
|
||||||
|
max_attempts: 3
|
||||||
|
retry_on: error
|
||||||
|
command: npm install
|
||||||
|
timeout_minutes: 10
|
||||||
|
- name: Build MacOS x64
|
||||||
|
run: npm run make -- --arch="x64"
|
||||||
|
- name: Build MacOS arm64
|
||||||
|
run: npm run make -- --arch="arm64"
|
||||||
|
- name: Upload MacOS x64 zip
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{env.BUILD_NAMEx64}}_ZIP
|
||||||
|
path: ./out/make/zip/darwin/x64/*.zip
|
||||||
|
- name: Upload MacOS x64 dmg
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{env.BUILD_NAMEx64}}_DMG
|
||||||
|
path: ./out/make/*x64*.dmg
|
||||||
|
- name: Upload MacOS arm64 zip
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{env.BUILD_NAMEarm64}}_ZIP
|
||||||
|
path: ./out/make/zip/darwin/arm64/*.zip
|
||||||
|
- name: Upload MacOS arm64 dmg
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{env.BUILD_NAMEarm64}}_DMG
|
||||||
|
path: ./out/make/*arm64*.dmg
|
||||||
|
build-windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install linux utils
|
||||||
|
run: choco install --force -y awk grep sed
|
||||||
|
- name: Setup environment
|
||||||
|
env:
|
||||||
|
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||||
|
run: |
|
||||||
|
# This is the hash of the commit for the PR
|
||||||
|
# when the action is triggered by PR, empty otherwise
|
||||||
|
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||||
|
# This is the hash of the commit when triggered by push
|
||||||
|
# but the hash of refs/pull/<n>/merge, which is different
|
||||||
|
# from the hash of the latest commit in the PR, that's
|
||||||
|
# why we try github.event.pull_request.head.sha first
|
||||||
|
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||||
|
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||||
|
VERSION=$(grep version package.json | sed 's/.*"\([0-9][0-9]*.[0-9]*.[0-9]*\)".*/\1/g')
|
||||||
|
echo "ACTIONS_STEP_DEBUG=true" >> $GITHUB_ENV
|
||||||
|
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||||
|
echo "BUILD_NAMEx64=inav-configurator_win32_x64_${VERSION}_${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||||
|
echo "BUILD_NAMEia32=inav-configurator_win32_ia32_${VERSION}_${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||||
|
shell: bash
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: 'npm'
|
||||||
|
- uses: engineerd/configurator@v0.0.10
|
||||||
|
with:
|
||||||
|
name: "Wix Toolset 3.1.4"
|
||||||
|
url: "https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314-binaries.zip"
|
||||||
|
pathInArchive: "/"
|
||||||
|
- name: Install deps
|
||||||
|
uses: nick-fields/retry@v2
|
||||||
|
with:
|
||||||
|
max_attempts: 3
|
||||||
|
retry_on: error
|
||||||
|
command: npm install
|
||||||
|
timeout_minutes: 10
|
||||||
|
- name: Build Win32 x64
|
||||||
|
run: npm run make -- --arch="x64"
|
||||||
|
- name: Build win32 ia32
|
||||||
|
run: npm run make -- --arch="ia32"
|
||||||
|
- name: Upload Windows x64 zip
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{env.BUILD_NAMEx64}}_ZIP
|
||||||
|
path: ./out/make/zip/win32/x64/*.zip
|
||||||
|
- name: Upload Windows x64 msi
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{env.BUILD_NAMEx64}}_MSI
|
||||||
|
path: ./out/make/wix/x64/*.msi
|
||||||
|
- name: Upload Windows ia32 zip
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{env.BUILD_NAMEia32}}_ZIP
|
||||||
|
path: ./out/make/zip/win32/ia32/*.zip
|
||||||
|
- name: Upload Windows ia32 msi
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{env.BUILD_NAMEia32}}_MSI
|
||||||
|
path: ./out/make/wix/ia32/*.msi
|
||||||
|
|
28
README.md
28
README.md
|
@ -20,32 +20,32 @@ everything, the hardware is not working, or you have any other _support_ problem
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Depending on the target operating system, _INAV Configurator_ is distributed as a _standalone_ application or Chrome App.
|
_INAV Configurator_ is distributed as a _standalone_ application.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
||||||
2. Download Configurator for Windows platform (win32 or win64 is present)
|
2. Download Configurator for Windows platform (ia32 or win64 is present)
|
||||||
3. Install
|
3. Install
|
||||||
* Extract ZIP archive and run the INAV Configurator app from the unpacked folder
|
* Extract ZIP archive and run the INAV Configurator app from the unpacked folder
|
||||||
* OR just use the setup program `INAV Configurator.msi`
|
* OR just use the setup program `INAV-Configurator_win32_arch_x.y.z.msi`, **arch** is your computer architecture (ia32 (32bit) or x64 (64bit)), **x.y.z** is the INAV Configurator version number.
|
||||||
|
|
||||||
4. 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
|
4. 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)
|
||||||
2. Download Configurator for Linux platform (linux32 and linux64 are present)
|
2. Download Configurator for Linux platform (only linux64 is present)
|
||||||
* **.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)
|
* **.rpm** is the Fedora installation file. Just download and install using `sudo dnf localinstall /path/to/INAV-Configurator_linux_x64-x.y.z.rpm` or open it with a package manager (e.g. via Files)
|
||||||
* **.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)
|
* **.deb** is the Debian/Ubuntu installation file. Just download and install using `sudo apt install /path/to/INAV-Configurator_linux_x64_x.y.z.deb` or open it with a package manager (e.g. via the File Manager)
|
||||||
* **.zip** is a universal archive. Download and continue with these instructions to install
|
* **.zip** is a universal archive. Download and continue with these instructions to install
|
||||||
3. Change to the directory containing the downloaded **zip** file
|
3. Change to the directory containing the downloaded **zip** file
|
||||||
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`.
|
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 **zip** archive
|
5. Extract **zip** archive
|
||||||
```
|
```
|
||||||
unzip INAV-Configurator_linuxNN_x.y.z.tar.gz -d /tmp/
|
unzip INAV-Configurator_linux_arch_x.y.z.zip -d /tmp/
|
||||||
```
|
```
|
||||||
**NN** is the bits of your OS. **x.y.z** is the INAV Configurator version number.
|
**arch** is your computer architecture (x64, armv7l, ...), **x.y.z** is the INAV Configurator version number.
|
||||||
|
|
||||||
6. If this is the first time installing INAV Configurator, create a home for its files
|
6. If this is the first time installing INAV Configurator, create a home for its files
|
||||||
```
|
```
|
||||||
|
@ -93,21 +93,27 @@ Options:
|
||||||
|
|
||||||
See [Electron Forge CLI Documentation](https://www.electronforge.io/cli#options-2) for details
|
See [Electron Forge CLI Documentation](https://www.electronforge.io/cli#options-2) for details
|
||||||
|
|
||||||
|
Note: Not all architectures are available for all platforms. For example, ia32 (32bit) support is not available for Linux.
|
||||||
|
Tested architectures:
|
||||||
|
- Windows: x64 and ia32
|
||||||
|
- Linux: x64 and armv7l
|
||||||
|
- MacOS: x64 and arm64
|
||||||
|
|
||||||
To build the setup program for windows, you have to install [WiX Toolset V3](https://github.com/wixtoolset/wix3/releases) and add the `bin` folder to you `PATH`, e.g.
|
To build the setup program for windows, you have to install [WiX Toolset V3](https://github.com/wixtoolset/wix3/releases) and add the `bin` folder to you `PATH`, e.g.
|
||||||
```C:\Program Files (x86)\WiX Toolset v3.14\bin```
|
```C:\Program Files (x86)\WiX Toolset v3.14\bin```
|
||||||
|
|
||||||
To build deb and rpm packages for Linux, you have to install the following packages:
|
To build deb and rpm packages for Linux, you have to install the following packages:
|
||||||
- Ubuntu/Debian: `dpkg, fakeroot, rpmbuild, build-essential, libudev-dev`
|
- Ubuntu/Debian: `dpkg, fakeroot, rpm, build-essential, libudev-dev`
|
||||||
- OpenSuse/Fedora: `dpkg, fakeroot, rpmbuild, systemd-devel, devel-basis (zypper install -t pattern devel_basis), zip`
|
- OpenSuse/Fedora: `dpkg, fakeroot, rpmbuild, systemd-devel, devel-basis (zypper install -t pattern devel_basis), zip`
|
||||||
|
|
||||||
Example (note the double -- ):
|
Example (note the double -- ):
|
||||||
``` npm run make -- --arch="x64" ```
|
```npm run make -- --arch="x64"```
|
||||||
|
|
||||||
### Running with debug | Inspector
|
### Running with debug | Inspector
|
||||||
|
|
||||||
To be able to open Inspector, set envorinment variable `NODE_ENV` to `develpoment` or set the flag directly when run `npm start`:
|
To be able to open Inspector, set envorinment variable `NODE_ENV` to `develpoment` or set the flag directly when run `npm start`:
|
||||||
|
|
||||||
```NODE_ENV=development npm start```
|
```NODE_ENV=development npm start``` or ```$env:NODE_ENV="development" | npm start``` for Windows PowerShell
|
||||||
|
|
||||||
Or use vscode and start a debug session `Debug Configurator` (Just hit F5!)
|
Or use vscode and start a debug session `Debug Configurator` (Just hit F5!)
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,8 @@ module.exports = {
|
||||||
name: '@electron-forge/maker-dmg',
|
name: '@electron-forge/maker-dmg',
|
||||||
config: {
|
config: {
|
||||||
name: "INAV Configurator",
|
name: "INAV Configurator",
|
||||||
background: "./assets/osx/dmg-background.png"
|
background: "./assets/osx/dmg-background.png",
|
||||||
|
icon: "./images/inav.icns"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -339,9 +339,6 @@
|
||||||
<div>
|
<div>
|
||||||
<span id="hardware-roundtrip"> </span>
|
<span id="hardware-roundtrip"> </span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<span id="drop-rate"> </span>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<span data-i18n="statusbar_arming_flags"></span> <span class="arming-flags">-</span>
|
<span data-i18n="statusbar_arming_flags"></span> <span class="arming-flags">-</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -255,8 +255,10 @@ class Connection {
|
||||||
getTimeout() {
|
getTimeout() {
|
||||||
if (this._bitrate >= 57600) {
|
if (this._bitrate >= 57600) {
|
||||||
return 3000;
|
return 3000;
|
||||||
} else {
|
} if (this._bitrate >= 19200) {
|
||||||
return 4000;
|
return 4000;
|
||||||
|
} else {
|
||||||
|
return 6000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,16 @@ class ConnectionSerial extends Connection {
|
||||||
GUI.log("Unable to list serial ports.");
|
GUI.log("Unable to list serial ports.");
|
||||||
} else {
|
} else {
|
||||||
ports.forEach(port => {
|
ports.forEach(port => {
|
||||||
devices.push(port.path);
|
if (GUI.operating_system == 'Linux') {
|
||||||
|
/* Limit to: USB serial, RFCOMM (BT), 6 legacy devices */
|
||||||
|
if (port.pnpId ||
|
||||||
|
port.path.match(/rfcomm\d*/) ||
|
||||||
|
port.path.match(/ttyS[0-5]$/)) {
|
||||||
|
devices.push(port.path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
devices.push(port.path);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (callback)
|
if (callback)
|
||||||
|
|
6
js/fc.js
6
js/fc.js
|
@ -1267,6 +1267,12 @@ var FC = {
|
||||||
hasOperand: [true, false],
|
hasOperand: [true, false],
|
||||||
output: "raw"
|
output: "raw"
|
||||||
},
|
},
|
||||||
|
53: {
|
||||||
|
name: "Disable GPS Sensor Fix",
|
||||||
|
operandType: "Set Flight Parameter",
|
||||||
|
hasOperand: [true, false],
|
||||||
|
output: "boolean"
|
||||||
|
},
|
||||||
54: {
|
54: {
|
||||||
name: "Mag calibration",
|
name: "Mag calibration",
|
||||||
operandType: "Set Flight Parameter",
|
operandType: "Set Flight Parameter",
|
||||||
|
|
13
js/gui.js
13
js/gui.js
|
@ -1,11 +1,12 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
const { dialog } = require("@electron/remote");
|
||||||
|
|
||||||
|
|
||||||
const CONFIGURATOR = require('./data_storage');
|
const CONFIGURATOR = require('./data_storage');
|
||||||
const Switchery = require('./libraries/switchery/switchery')
|
const Switchery = require('./libraries/switchery/switchery')
|
||||||
const MSP = require('./msp');
|
const MSP = require('./msp');
|
||||||
const FC = require('./fc');
|
const FC = require('./fc');
|
||||||
const interval = require('./intervals');
|
const interval = require('./intervals');
|
||||||
const mspBalancedInterval = require('./msp_balanced_interval');
|
|
||||||
const { scaleRangeInt } = require('./helpers');
|
const { scaleRangeInt } = require('./helpers');
|
||||||
const i18n = require('./localization');
|
const i18n = require('./localization');
|
||||||
|
|
||||||
|
@ -91,8 +92,7 @@ GUI_control.prototype.log = function (message) {
|
||||||
GUI_control.prototype.tab_switch_cleanup = function (callback) {
|
GUI_control.prototype.tab_switch_cleanup = function (callback) {
|
||||||
MSP.callbacks_cleanup(); // we don't care about any old data that might or might not arrive
|
MSP.callbacks_cleanup(); // we don't care about any old data that might or might not arrive
|
||||||
|
|
||||||
interval.killAll(['global_data_refresh', 'msp-load-update']);
|
interval.killAll(['global_data_refresh', 'msp-load-update', 'ltm-connection-check']);
|
||||||
mspBalancedInterval.flush();
|
|
||||||
|
|
||||||
if (this.active_tab) {
|
if (this.active_tab) {
|
||||||
TABS[this.active_tab].cleanup(callback);
|
TABS[this.active_tab].cleanup(callback);
|
||||||
|
@ -529,6 +529,13 @@ GUI_control.prototype.update_dataflash_global = function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't use alert() in Electron, it has a nasty bug: https://github.com/electron/electron/issues/31917
|
||||||
|
*/
|
||||||
|
GUI_control.prototype.alert = function(message) {
|
||||||
|
dialog.showMessageBoxSync({ message: message, icon: "./images/inav_icon_128.png" });
|
||||||
|
}
|
||||||
|
|
||||||
// initialize object into GUI variable
|
// initialize object into GUI variable
|
||||||
var GUI = new GUI_control();
|
var GUI = new GUI_control();
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,8 @@ var interval = function () {
|
||||||
publicScope.killAll = function (keep_array) {
|
publicScope.killAll = function (keep_array) {
|
||||||
var timers_killed = 0;
|
var timers_killed = 0;
|
||||||
|
|
||||||
|
console.log('Killing all intervals except: ' + keep_array);
|
||||||
|
|
||||||
for (var i = (privateScope.intervals.length - 1); i >= 0; i--) { // reverse iteration
|
for (var i = (privateScope.intervals.length - 1); i >= 0; i--) { // reverse iteration
|
||||||
var keep = false;
|
var keep = false;
|
||||||
if (keep_array) { // only run through the array if it exists
|
if (keep_array) { // only run through the array if it exists
|
||||||
|
@ -131,6 +133,10 @@ var interval = function () {
|
||||||
return timers_killed;
|
return timers_killed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
publicScope.list = function () {
|
||||||
|
return privateScope.intervals;
|
||||||
|
};
|
||||||
|
|
||||||
return publicScope;
|
return publicScope;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
|
26
js/main.js
26
js/main.js
|
@ -1,4 +1,4 @@
|
||||||
const { app, BrowserWindow, ipcMain } = require('electron');
|
const { app, BrowserWindow, ipcMain, Menu, MenuItem } = require('electron');
|
||||||
const windowStateKeeper = require('electron-window-state');
|
const windowStateKeeper = require('electron-window-state');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const Store = require('electron-store');
|
const Store = require('electron-store');
|
||||||
|
@ -53,6 +53,10 @@ function createDeviceChooser() {
|
||||||
}
|
}
|
||||||
|
|
||||||
app.on('ready', () => {
|
app.on('ready', () => {
|
||||||
|
createWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
function createWindow() {
|
||||||
|
|
||||||
let mainWindowState = windowStateKeeper({
|
let mainWindowState = windowStateKeeper({
|
||||||
defaultWidth: 800,
|
defaultWidth: 800,
|
||||||
|
@ -72,6 +76,24 @@ app.on('ready', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mainWindow.webContents.on('context-menu', (_, props) => {
|
||||||
|
const menu = new Menu() ;
|
||||||
|
menu.append(new MenuItem({ label: "Undo", role: "undo", accelerator: 'CmdOrCtrl+Z', visible: props.isEditable }));
|
||||||
|
menu.append(new MenuItem({ label: "Redo", role: "redo", accelerator: 'CmdOrCtrl+Y', visible: props.isEditable }));
|
||||||
|
menu.append(new MenuItem({ type: "separator", visible: props.isEditable }));
|
||||||
|
menu.append(new MenuItem({ label: 'Cut', role: 'cut', accelerator: 'CmdOrCtrl+X', visible: props.isEditable && props.selectionText }));
|
||||||
|
menu.append(new MenuItem({ label: 'Copy', role: 'copy', accelerator: 'CmdOrCtrl+C', visible: props.selectionText }));
|
||||||
|
menu.append(new MenuItem({ label: 'Paste', role: 'paste', accelerator: 'CmdOrCtrl+V', visible: props.isEditable }));
|
||||||
|
menu.append(new MenuItem({ label: "Select all", role: 'selectAll', accelerator: 'CmdOrCtrl+A', visible: props.isEditable}));
|
||||||
|
|
||||||
|
menu.items.forEach(item => {
|
||||||
|
if (item.visible) {
|
||||||
|
menu.popup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
|
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
selectBluetoothCallback = callback;
|
selectBluetoothCallback = callback;
|
||||||
|
@ -147,7 +169,7 @@ app.on('ready', () => {
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
mainWindow.webContents.openDevTools();
|
mainWindow.webContents.openDevTools();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
app.on('window-all-closed', () => {
|
app.on('window-all-closed', () => {
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
const MSPCodes = require('./msp/MSPCodes')
|
const MSPCodes = require('./msp/MSPCodes')
|
||||||
const mspQueue = require('./serial_queue');
|
const mspQueue = require('./serial_queue');
|
||||||
|
const eventFrequencyAnalyzer = require('./eventFrequencyAnalyzer');
|
||||||
|
const timeout = require('./timeouts');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -265,7 +267,9 @@ var MSP = {
|
||||||
/*
|
/*
|
||||||
* Free port
|
* Free port
|
||||||
*/
|
*/
|
||||||
mspQueue.freeHardLock();
|
timeout.add('delayedFreeHardLock', function() {
|
||||||
|
mspQueue.freeHardLock();
|
||||||
|
}, 10);
|
||||||
|
|
||||||
// Reset variables
|
// Reset variables
|
||||||
this.message_length_received = 0;
|
this.message_length_received = 0;
|
||||||
|
@ -301,6 +305,8 @@ var MSP = {
|
||||||
var checksum;
|
var checksum;
|
||||||
var ii;
|
var ii;
|
||||||
|
|
||||||
|
eventFrequencyAnalyzer.put('MPS ' + code);
|
||||||
|
|
||||||
if (!protocolVersion) {
|
if (!protocolVersion) {
|
||||||
protocolVersion = this.protocolVersion;
|
protocolVersion = this.protocolVersion;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ const ProgrammingPid = require('./../programmingPid');
|
||||||
const Safehome = require('./../safehome');
|
const Safehome = require('./../safehome');
|
||||||
const { FwApproach } = require('./../fwApproach');
|
const { FwApproach } = require('./../fwApproach');
|
||||||
const Waypoint = require('./../waypoint');
|
const Waypoint = require('./../waypoint');
|
||||||
|
const mspDeduplicationQueue = require('./mspDeduplicationQueue');
|
||||||
|
const mspStatistics = require('./mspStatistics');
|
||||||
|
|
||||||
var mspHelper = (function () {
|
var mspHelper = (function () {
|
||||||
var self = {};
|
var self = {};
|
||||||
|
@ -922,7 +924,7 @@ var mspHelper = (function () {
|
||||||
|
|
||||||
directions = [];
|
directions = [];
|
||||||
for (directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
|
for (directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
|
||||||
if (bit_check(directionMask, directionLetterIndex)) {
|
if (BitHelper.bit_check(directionMask, directionLetterIndex)) {
|
||||||
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
|
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -932,7 +934,7 @@ var mspHelper = (function () {
|
||||||
|
|
||||||
functions = [];
|
functions = [];
|
||||||
for (var functionLetterIndex = 0; functionLetterIndex < MSP.ledFunctionLetters.length; functionLetterIndex++) {
|
for (var functionLetterIndex = 0; functionLetterIndex < MSP.ledFunctionLetters.length; functionLetterIndex++) {
|
||||||
if (bit_check(functionMask, functionLetterIndex)) {
|
if (BitHelper.bit_check(functionMask, functionLetterIndex)) {
|
||||||
functions.push(MSP.ledFunctionLetters[functionLetterIndex]);
|
functions.push(MSP.ledFunctionLetters[functionLetterIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -962,7 +964,7 @@ var mspHelper = (function () {
|
||||||
|
|
||||||
var overlayMask = (mask >> 12) & 0x3F;
|
var overlayMask = (mask >> 12) & 0x3F;
|
||||||
for (var overlayLetterIndex = 0; overlayLetterIndex < MSP.ledOverlayLetters.length; overlayLetterIndex++) {
|
for (var overlayLetterIndex = 0; overlayLetterIndex < MSP.ledOverlayLetters.length; overlayLetterIndex++) {
|
||||||
if (bit_check(overlayMask, overlayLetterIndex)) {
|
if (BitHelper.bit_check(overlayMask, overlayLetterIndex)) {
|
||||||
functions.push(MSP.ledOverlayLetters[overlayLetterIndex]);
|
functions.push(MSP.ledOverlayLetters[overlayLetterIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -971,7 +973,7 @@ var mspHelper = (function () {
|
||||||
|
|
||||||
directions = [];
|
directions = [];
|
||||||
for (directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
|
for (directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
|
||||||
if (bit_check(directionMask, directionLetterIndex)) {
|
if (BitHelper.bit_check(directionMask, directionLetterIndex)) {
|
||||||
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
|
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1019,7 @@ var mspHelper = (function () {
|
||||||
|
|
||||||
var overlayMask = (mask >> 16) & 0xFF;
|
var overlayMask = (mask >> 16) & 0xFF;
|
||||||
for (var overlayLetterIndex = 0; overlayLetterIndex < MSP.ledOverlayLetters.length; overlayLetterIndex++) {
|
for (var overlayLetterIndex = 0; overlayLetterIndex < MSP.ledOverlayLetters.length; overlayLetterIndex++) {
|
||||||
if (bit_check(overlayMask, overlayLetterIndex)) {
|
if (BitHelper.bit_check(overlayMask, overlayLetterIndex)) {
|
||||||
functions.push(MSP.ledOverlayLetters[overlayLetterIndex]);
|
functions.push(MSP.ledOverlayLetters[overlayLetterIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1026,7 +1028,7 @@ var mspHelper = (function () {
|
||||||
|
|
||||||
directions = [];
|
directions = [];
|
||||||
for (directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
|
for (directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
|
||||||
if (bit_check(directionMask, directionLetterIndex)) {
|
if (BitHelper.bit_check(directionMask, directionLetterIndex)) {
|
||||||
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
|
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1618,9 +1620,17 @@ var mspHelper = (function () {
|
||||||
*/
|
*/
|
||||||
if (dataHandler.callbacks[i]) {
|
if (dataHandler.callbacks[i]) {
|
||||||
mspQueue.putRoundtrip(new Date().getTime() - dataHandler.callbacks[i].createdOn);
|
mspQueue.putRoundtrip(new Date().getTime() - dataHandler.callbacks[i].createdOn);
|
||||||
mspQueue.putHardwareRoundtrip(new Date().getTime() - dataHandler.callbacks[i].sentOn);
|
|
||||||
|
const hardwareRountrip = new Date().getTime() - dataHandler.callbacks[i].sentOn;
|
||||||
|
|
||||||
|
mspQueue.putHardwareRoundtrip(hardwareRountrip);
|
||||||
|
|
||||||
|
mspStatistics.add(dataHandler.code, hardwareRountrip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//remove message from queue as received
|
||||||
|
mspDeduplicationQueue.remove(dataHandler.code);
|
||||||
|
|
||||||
// remove object from array
|
// remove object from array
|
||||||
dataHandler.callbacks.splice(i, 1);
|
dataHandler.callbacks.splice(i, 1);
|
||||||
|
|
||||||
|
@ -2260,7 +2270,7 @@ var mspHelper = (function () {
|
||||||
buffer.push(BitHelper.lowByte(servoConfiguration.middle));
|
buffer.push(BitHelper.lowByte(servoConfiguration.middle));
|
||||||
buffer.push(BitHelper.highByte(servoConfiguration.middle));
|
buffer.push(BitHelper.highByte(servoConfiguration.middle));
|
||||||
|
|
||||||
buffer.push(lowByte(servoConfiguration.rate));
|
buffer.push(BitHelper.lowByte(servoConfiguration.rate));
|
||||||
|
|
||||||
// prepare for next iteration
|
// prepare for next iteration
|
||||||
servoIndex++;
|
servoIndex++;
|
||||||
|
@ -2650,7 +2660,7 @@ var mspHelper = (function () {
|
||||||
|
|
||||||
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 + 16);
|
mask |= BitHelper.bit_set(mask, bitIndex + 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2662,9 +2672,9 @@ var mspHelper = (function () {
|
||||||
bitIndex = MSP.ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
|
bitIndex = MSP.ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
|
||||||
if (bitIndex >= 0) {
|
if (bitIndex >= 0) {
|
||||||
if(bitIndex < 4) {
|
if(bitIndex < 4) {
|
||||||
mask |= bit_set(mask, bitIndex + 28);
|
mask |= BitHelper.bit_set(mask, bitIndex + 28);
|
||||||
} else {
|
} else {
|
||||||
extra |= bit_set(extra, bitIndex - 4);
|
extra |= BitHelper.bit_set(extra, bitIndex - 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3065,6 +3075,7 @@ var mspHelper = (function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
self._getSetting = function (name) {
|
self._getSetting = function (name) {
|
||||||
|
console.log("Getting setting " + name);
|
||||||
if (FC.SETTINGS[name]) {
|
if (FC.SETTINGS[name]) {
|
||||||
return Promise.resolve(FC.SETTINGS[name]);
|
return Promise.resolve(FC.SETTINGS[name]);
|
||||||
}
|
}
|
||||||
|
|
41
js/msp/mspDeduplicationQueue.js
Normal file
41
js/msp/mspDeduplicationQueue.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module is a queue for deduplication of MSP requests.
|
||||||
|
* We do not want to process the same request multiple times unless response is received.
|
||||||
|
* This improves wireless handling and lower amount of data that is put on the air
|
||||||
|
*/
|
||||||
|
var mspDeduplicationQueue = function() {
|
||||||
|
|
||||||
|
let publicScope = {},
|
||||||
|
privateScope = {};
|
||||||
|
|
||||||
|
privateScope.queue = [];
|
||||||
|
|
||||||
|
publicScope.put = function(item) {
|
||||||
|
privateScope.queue.push(item);
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.remove = function(item) {
|
||||||
|
const index = privateScope.queue.indexOf(item);
|
||||||
|
if (index > -1) {
|
||||||
|
privateScope.queue.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.check = function(item) {
|
||||||
|
return privateScope.queue.includes(item);
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.flush = function() {
|
||||||
|
privateScope.queue = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.get = function() {
|
||||||
|
return privateScope.queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
return publicScope;
|
||||||
|
}();
|
||||||
|
|
||||||
|
module.exports = mspDeduplicationQueue;
|
39
js/msp/mspStatistics.js
Normal file
39
js/msp/mspStatistics.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var mspStatistics = function() {
|
||||||
|
|
||||||
|
let publicScope = {},
|
||||||
|
privateScope = {};
|
||||||
|
|
||||||
|
privateScope.statistics = {};
|
||||||
|
|
||||||
|
|
||||||
|
publicScope.add = function(code, duration) {
|
||||||
|
if (!privateScope.statistics[code]) {
|
||||||
|
privateScope.statistics[code] = {
|
||||||
|
ctime: new Date().getTime(),
|
||||||
|
count: 0,
|
||||||
|
duration: 0,
|
||||||
|
average: 0,
|
||||||
|
callsPerSecond: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
privateScope.statistics[code].count++;
|
||||||
|
privateScope.statistics[code].duration += duration;
|
||||||
|
privateScope.statistics[code].average = privateScope.statistics[code].duration / privateScope.statistics[code].count;
|
||||||
|
privateScope.statistics[code].callsPerSecond = privateScope.statistics[code].count / ((new Date().getTime() - privateScope.statistics[code].ctime) / 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.get = function() {
|
||||||
|
return privateScope.statistics;
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.reset = function() {
|
||||||
|
privateScope.statistics = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
return publicScope;
|
||||||
|
|
||||||
|
}();
|
||||||
|
|
||||||
|
module.exports = mspStatistics;
|
|
@ -1,75 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const mspQueue = require('./serial_queue');
|
|
||||||
const interval = require('./intervals');
|
|
||||||
|
|
||||||
var mspBalancedInterval = (function (mspQueue, intervalHandler) {
|
|
||||||
|
|
||||||
var publicScope = {},
|
|
||||||
privateScope = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* How often balancing should be executed [Hz]
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
privateScope.balancingFrequency = 0.5;
|
|
||||||
|
|
||||||
privateScope.intervals = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {string} name
|
|
||||||
* @param {number} requestedInterval
|
|
||||||
* @param {number} messagesInInterval
|
|
||||||
* @param {function} code
|
|
||||||
*/
|
|
||||||
publicScope.add = function (name, requestedInterval, messagesInInterval, code) {
|
|
||||||
privateScope.intervals.push({
|
|
||||||
name: name,
|
|
||||||
requestedInterval: requestedInterval,
|
|
||||||
messagesInInterval: messagesInInterval,
|
|
||||||
code: code
|
|
||||||
});
|
|
||||||
|
|
||||||
intervalHandler.add(name, code, mspQueue.getIntervalPrediction(requestedInterval, messagesInInterval));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Periodically executed balancing handler
|
|
||||||
*/
|
|
||||||
publicScope.balancer = function () {
|
|
||||||
|
|
||||||
var interval;
|
|
||||||
|
|
||||||
for (var i in privateScope.intervals) {
|
|
||||||
if (privateScope.intervals.hasOwnProperty(i)) {
|
|
||||||
interval = privateScope.intervals[i];
|
|
||||||
|
|
||||||
intervalHandler.remove(interval.name);
|
|
||||||
intervalHandler.add(
|
|
||||||
interval.name,
|
|
||||||
interval.code,
|
|
||||||
mspQueue.getIntervalPrediction(
|
|
||||||
interval.requestedInterval,
|
|
||||||
interval.messagesInInterval
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Real interval cleaning happens win interval.killAll method
|
|
||||||
* both methods have to be executed
|
|
||||||
*/
|
|
||||||
publicScope.flush = function () {
|
|
||||||
privateScope.intervals = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
setInterval(publicScope.balancer, Math.round(1000 / privateScope.balancingFrequency));
|
|
||||||
|
|
||||||
return publicScope;
|
|
||||||
})(mspQueue, interval);
|
|
||||||
|
|
||||||
module.exports = mspBalancedInterval;
|
|
|
@ -104,11 +104,6 @@ const mspQueue = require('./serial_queue');
|
||||||
|
|
||||||
if (!stoppped && GUI.active_tab != 'cli') {
|
if (!stoppped && GUI.active_tab != 'cli') {
|
||||||
|
|
||||||
if (mspQueue.shouldDropStatus()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS, false, false);
|
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS, false, false);
|
||||||
MSP.send_message(MSPCodes.MSPV2_INAV_STATUS, false, false);
|
MSP.send_message(MSPCodes.MSPV2_INAV_STATUS, false, false);
|
||||||
MSP.send_message(MSPCodes.MSP_ACTIVEBOXES, false, false);
|
MSP.send_message(MSPCodes.MSP_ACTIVEBOXES, false, false);
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
|
|
||||||
var PidController = function () {
|
|
||||||
|
|
||||||
var self = {},
|
|
||||||
privateScope = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
privateScope.target = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {{P: null, I: null, D: null}}
|
|
||||||
*/
|
|
||||||
privateScope.gains = {
|
|
||||||
P: null,
|
|
||||||
I: null,
|
|
||||||
D: null
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
privateScope.Iterm = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {{min: number, max: number}}
|
|
||||||
*/
|
|
||||||
privateScope.ItermLimit = {
|
|
||||||
min: -1000,
|
|
||||||
max: 1000
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
privateScope.previousError = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {{min: number, max: number, minThreshold: number}}
|
|
||||||
*/
|
|
||||||
privateScope.output = {
|
|
||||||
min: null,
|
|
||||||
max: null,
|
|
||||||
minThreshold: null
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {number} value
|
|
||||||
*/
|
|
||||||
self.setTarget = function (value) {
|
|
||||||
privateScope.target = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} Pgain
|
|
||||||
* @param {number} Igain
|
|
||||||
* @param {number} Dgain
|
|
||||||
*/
|
|
||||||
self.setGains = function (Pgain, Igain, Dgain) {
|
|
||||||
privateScope.gains.P = Pgain;
|
|
||||||
privateScope.gains.I = Igain;
|
|
||||||
privateScope.gains.D = Dgain;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets min and max value for output
|
|
||||||
* @param {number} min
|
|
||||||
* @param {number} max
|
|
||||||
* @param {number} minThreshold if output is below this value, [min] is returned
|
|
||||||
*/
|
|
||||||
self.setOutput = function (min, max, minThreshold) {
|
|
||||||
privateScope.output.min = min;
|
|
||||||
privateScope.output.max = max;
|
|
||||||
privateScope.output.minThreshold = minThreshold;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets upper and lower limit for Iterm accumulator
|
|
||||||
* @param {number} min
|
|
||||||
* @param {number} max
|
|
||||||
*/
|
|
||||||
self.setItermLimit = function (min, max) {
|
|
||||||
privateScope.ItermLimit.min = min;
|
|
||||||
privateScope.ItermLimit.max = max;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes PID controller based on current value and target
|
|
||||||
* @param {number} current
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
self.run = function (current) {
|
|
||||||
var error = current - privateScope.target,
|
|
||||||
Pterm = error * privateScope.gains.P,
|
|
||||||
Dterm = (error - privateScope.previousError) * privateScope.gains.D,
|
|
||||||
output;
|
|
||||||
|
|
||||||
privateScope.previousError = error;
|
|
||||||
|
|
||||||
privateScope.Iterm += error * privateScope.gains.I;
|
|
||||||
if (privateScope.Iterm > privateScope.ItermLimit.max) {
|
|
||||||
privateScope.Iterm = privateScope.ItermLimit.max;
|
|
||||||
} else if (privateScope.Iterm < privateScope.ItermLimit.min) {
|
|
||||||
privateScope.Iterm = privateScope.ItermLimit.min;
|
|
||||||
}
|
|
||||||
|
|
||||||
output = Pterm + privateScope.Iterm + Dterm;
|
|
||||||
if (output < privateScope.output.minThreshold) {
|
|
||||||
output = privateScope.output.min;
|
|
||||||
} else if (output > privateScope.output.max) {
|
|
||||||
output = privateScope.output.max;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
};
|
|
||||||
|
|
||||||
return self;
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = PidController;
|
|
|
@ -18,7 +18,6 @@ const interval = require('./intervals');
|
||||||
const periodicStatusUpdater = require('./periodicStatusUpdater');
|
const periodicStatusUpdater = require('./periodicStatusUpdater');
|
||||||
const mspQueue = require('./serial_queue');
|
const mspQueue = require('./serial_queue');
|
||||||
const timeout = require('./timeouts');
|
const timeout = require('./timeouts');
|
||||||
const mspBalancedInterval = require('./msp_balanced_interval');
|
|
||||||
const defaultsDialog = require('./defaults_dialog');
|
const defaultsDialog = require('./defaults_dialog');
|
||||||
const { SITLProcess } = require('./sitl');
|
const { SITLProcess } = require('./sitl');
|
||||||
const update = require('./globalUpdates');
|
const update = require('./globalUpdates');
|
||||||
|
@ -27,6 +26,7 @@ const BOARD = require('./boards');
|
||||||
const jBox = require('./libraries/jBox/jBox.min');
|
const jBox = require('./libraries/jBox/jBox.min');
|
||||||
const groundstation = require('./groundstation');
|
const groundstation = require('./groundstation');
|
||||||
const ltmDecoder = require('./ltmDecoder');
|
const ltmDecoder = require('./ltmDecoder');
|
||||||
|
const mspDeduplicationQueue = require('./msp/mspDeduplicationQueue');
|
||||||
|
|
||||||
var SerialBackend = (function () {
|
var SerialBackend = (function () {
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@ var SerialBackend = (function () {
|
||||||
|
|
||||||
privateScope.isDemoRunning = false;
|
privateScope.isDemoRunning = false;
|
||||||
|
|
||||||
|
privateScope.isWirelessMode = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle "Wireless" mode with strict queueing of messages
|
* Handle "Wireless" mode with strict queueing of messages
|
||||||
*/
|
*/
|
||||||
|
@ -215,7 +217,6 @@ var SerialBackend = (function () {
|
||||||
|
|
||||||
timeout.killAll();
|
timeout.killAll();
|
||||||
interval.killAll(['global_data_refresh', 'msp-load-update']);
|
interval.killAll(['global_data_refresh', 'msp-load-update']);
|
||||||
mspBalancedInterval.flush();
|
|
||||||
|
|
||||||
if (CONFIGURATOR.cliActive) {
|
if (CONFIGURATOR.cliActive) {
|
||||||
GUI.tab_switch_cleanup(finishDisconnect);
|
GUI.tab_switch_cleanup(finishDisconnect);
|
||||||
|
@ -237,6 +238,7 @@ var SerialBackend = (function () {
|
||||||
mspQueue.flush();
|
mspQueue.flush();
|
||||||
mspQueue.freeHardLock();
|
mspQueue.freeHardLock();
|
||||||
mspQueue.freeSoftLock();
|
mspQueue.freeSoftLock();
|
||||||
|
mspDeduplicationQueue.flush();
|
||||||
|
|
||||||
CONFIGURATOR.connection.disconnect(privateScope.onClosed);
|
CONFIGURATOR.connection.disconnect(privateScope.onClosed);
|
||||||
MSP.disconnect_cleanup();
|
MSP.disconnect_cleanup();
|
||||||
|
@ -374,6 +376,7 @@ var SerialBackend = (function () {
|
||||||
mspQueue.flush();
|
mspQueue.flush();
|
||||||
mspQueue.freeHardLock();
|
mspQueue.freeHardLock();
|
||||||
mspQueue.freeSoftLock();
|
mspQueue.freeSoftLock();
|
||||||
|
mspDeduplicationQueue.flush();
|
||||||
CONFIGURATOR.connection.emptyOutputBuffer();
|
CONFIGURATOR.connection.emptyOutputBuffer();
|
||||||
|
|
||||||
$('div.connect_controls a').click(); // disconnect
|
$('div.connect_controls a').click(); // disconnect
|
||||||
|
@ -451,35 +454,35 @@ var SerialBackend = (function () {
|
||||||
$('.mode-disconnected').hide();
|
$('.mode-disconnected').hide();
|
||||||
$('.mode-connected').show();
|
$('.mode-connected').show();
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_DATAFLASH_SUMMARY, false, false);
|
MSP.send_message(MSPCodes.MSP_DATAFLASH_SUMMARY, false, false, function () {
|
||||||
|
$('#sensor-status').show();
|
||||||
|
$('#portsinput').hide();
|
||||||
|
$('#dataflash_wrapper_global').show();
|
||||||
|
|
||||||
$('#sensor-status').show();
|
/*
|
||||||
$('#portsinput').hide();
|
* Get BOXNAMES since it is used for some reason....
|
||||||
$('#dataflash_wrapper_global').show();
|
*/
|
||||||
|
MSP.send_message(MSPCodes.MSP_BOXNAMES, false, false, function () {
|
||||||
|
/*
|
||||||
|
* Init PIDs bank with a length that depends on the version
|
||||||
|
*/
|
||||||
|
let pidCount = 11;
|
||||||
|
|
||||||
/*
|
for (let i = 0; i < pidCount; i++) {
|
||||||
* Get BOXNAMES since it is used for some reason....
|
FC.PIDs.push(new Array(4));
|
||||||
*/
|
}
|
||||||
MSP.send_message(MSPCodes.MSP_BOXNAMES, false, false);
|
|
||||||
|
|
||||||
/*
|
interval.add('msp-load-update', function () {
|
||||||
* Init PIDs bank with a length that depends on the version
|
$('#msp-version').text("MSP version: " + MSP.protocolVersion.toFixed(0));
|
||||||
*/
|
$('#msp-load').text("MSP load: " + mspQueue.getLoad().toFixed(1));
|
||||||
let pidCount = 11;
|
$('#msp-roundtrip').text("MSP round trip: " + mspQueue.getRoundtrip().toFixed(0));
|
||||||
|
$('#hardware-roundtrip').text("HW round trip: " + mspQueue.getHardwareRoundtrip().toFixed(0));
|
||||||
|
}, 100);
|
||||||
|
|
||||||
for (let i = 0; i < pidCount; i++) {
|
interval.add('global_data_refresh', periodicStatusUpdater.run, periodicStatusUpdater.getUpdateInterval(CONFIGURATOR.connection.bitrate), false);
|
||||||
FC.PIDs.push(new Array(4));
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
interval.add('msp-load-update', function () {
|
|
||||||
$('#msp-version').text("MSP version: " + MSP.protocolVersion.toFixed(0));
|
|
||||||
$('#msp-load').text("MSP load: " + mspQueue.getLoad().toFixed(1));
|
|
||||||
$('#msp-roundtrip').text("MSP round trip: " + mspQueue.getRoundtrip().toFixed(0));
|
|
||||||
$('#hardware-roundtrip').text("HW round trip: " + mspQueue.getHardwareRoundtrip().toFixed(0));
|
|
||||||
$('#drop-rate').text("Drop ratio: " + mspQueue.getDropRatio().toFixed(0) + "%");
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
interval.add('global_data_refresh', periodicStatusUpdater.run, periodicStatusUpdater.getUpdateInterval(CONFIGURATOR.connection.bitrate), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
privateScope.onClosed = function (result) {
|
privateScope.onClosed = function (result) {
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
const CONFIGURATOR = require('./data_storage');
|
const CONFIGURATOR = require('./data_storage');
|
||||||
const MSPCodes = require('./msp/MSPCodes');
|
const MSPCodes = require('./msp/MSPCodes');
|
||||||
const SimpleSmoothFilter = require('./simple_smooth_filter');
|
const SimpleSmoothFilter = require('./simple_smooth_filter');
|
||||||
const PidController = require('./pid_controller');
|
|
||||||
const eventFrequencyAnalyzer = require('./eventFrequencyAnalyzer');
|
const eventFrequencyAnalyzer = require('./eventFrequencyAnalyzer');
|
||||||
|
const mspDeduplicationQueue = require('./msp/mspDeduplicationQueue');
|
||||||
|
|
||||||
var mspQueue = function () {
|
var mspQueue = function () {
|
||||||
|
|
||||||
|
@ -27,29 +27,9 @@ var mspQueue = function () {
|
||||||
|
|
||||||
privateScope.currentLoad = 0;
|
privateScope.currentLoad = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* PID controller used to perform throttling
|
|
||||||
* @type {PidController}
|
|
||||||
*/
|
|
||||||
privateScope.loadPidController = new PidController();
|
|
||||||
privateScope.loadPidController.setTarget(privateScope.targetLoad);
|
|
||||||
privateScope.loadPidController.setOutput(0, 99, 0);
|
|
||||||
privateScope.loadPidController.setGains(5, 6, 3);
|
|
||||||
privateScope.loadPidController.setItermLimit(0, 90);
|
|
||||||
|
|
||||||
privateScope.dropRatio = 0;
|
|
||||||
|
|
||||||
privateScope.removeCallback = null;
|
privateScope.removeCallback = null;
|
||||||
privateScope.putCallback = null;
|
privateScope.putCallback = null;
|
||||||
|
|
||||||
publicScope.computeDropRatio = function () {
|
|
||||||
privateScope.dropRatio = privateScope.loadPidController.run(publicScope.getLoad());
|
|
||||||
};
|
|
||||||
|
|
||||||
publicScope.getDropRatio = function () {
|
|
||||||
return privateScope.dropRatio;
|
|
||||||
};
|
|
||||||
|
|
||||||
privateScope.queue = [];
|
privateScope.queue = [];
|
||||||
|
|
||||||
privateScope.softLock = false;
|
privateScope.softLock = false;
|
||||||
|
@ -86,6 +66,10 @@ var mspQueue = function () {
|
||||||
privateScope.lockMethod = method;
|
privateScope.lockMethod = method;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
publicScope.getLockMethod = function () {
|
||||||
|
return privateScope.lockMethod;
|
||||||
|
};
|
||||||
|
|
||||||
publicScope.setSoftLock = function () {
|
publicScope.setSoftLock = function () {
|
||||||
privateScope.softLock = new Date().getTime();
|
privateScope.softLock = new Date().getTime();
|
||||||
};
|
};
|
||||||
|
@ -160,6 +144,7 @@ var mspQueue = function () {
|
||||||
|
|
||||||
request.timer = setTimeout(function () {
|
request.timer = setTimeout(function () {
|
||||||
console.log('MSP data request timed-out: ' + request.code);
|
console.log('MSP data request timed-out: ' + request.code);
|
||||||
|
mspDeduplicationQueue.remove(request.code);
|
||||||
/*
|
/*
|
||||||
* Remove current callback
|
* Remove current callback
|
||||||
*/
|
*/
|
||||||
|
@ -223,10 +208,19 @@ var mspQueue = function () {
|
||||||
*/
|
*/
|
||||||
publicScope.put = function (mspRequest) {
|
publicScope.put = function (mspRequest) {
|
||||||
|
|
||||||
|
const isMessageInQueue = mspDeduplicationQueue.check(mspRequest.code);
|
||||||
|
|
||||||
|
if (isMessageInQueue) {
|
||||||
|
eventFrequencyAnalyzer.put('MSP Duplicate ' + mspRequest.code);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (privateScope.queueLocked === true) {
|
if (privateScope.queueLocked === true) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mspDeduplicationQueue.put(mspRequest.code);
|
||||||
|
|
||||||
privateScope.queue.push(mspRequest);
|
privateScope.queue.push(mspRequest);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
@ -269,7 +263,6 @@ var mspQueue = function () {
|
||||||
|
|
||||||
publicScope.balancer = function () {
|
publicScope.balancer = function () {
|
||||||
privateScope.currentLoad = privateScope.loadFilter.get();
|
privateScope.currentLoad = privateScope.loadFilter.get();
|
||||||
publicScope.computeDropRatio();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Also, check if port lock if hanging. Free is so
|
* Also, check if port lock if hanging. Free is so
|
||||||
|
@ -277,29 +270,25 @@ var mspQueue = function () {
|
||||||
var currentTimestamp = new Date().getTime(),
|
var currentTimestamp = new Date().getTime(),
|
||||||
threshold = publicScope.getHardwareRoundtrip() * 3;
|
threshold = publicScope.getHardwareRoundtrip() * 3;
|
||||||
|
|
||||||
if (threshold > 1000) {
|
if (threshold > 5000) {
|
||||||
|
threshold = 5000;
|
||||||
|
}
|
||||||
|
if (threshold < 1000) {
|
||||||
threshold = 1000;
|
threshold = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (privateScope.softLock !== false && currentTimestamp - privateScope.softLock > threshold) {
|
if (privateScope.softLock !== false && currentTimestamp - privateScope.softLock > threshold) {
|
||||||
privateScope.softLock = false;
|
publicScope.freeSoftLock();
|
||||||
eventFrequencyAnalyzer.put('force free soft lock');
|
eventFrequencyAnalyzer.put('force free soft lock');
|
||||||
}
|
}
|
||||||
if (privateScope.hardLock !== false && currentTimestamp - privateScope.hardLock > threshold) {
|
if (privateScope.hardLock !== false && currentTimestamp - privateScope.hardLock > threshold) {
|
||||||
privateScope.hardLock = false;
|
console.log('Force free hard lock');
|
||||||
|
publicScope.freeHardLock();
|
||||||
eventFrequencyAnalyzer.put('force free hard lock');
|
eventFrequencyAnalyzer.put('force free hard lock');
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
publicScope.shouldDrop = function () {
|
|
||||||
return (Math.round(Math.random()*100) < privateScope.dropRatio);
|
|
||||||
};
|
|
||||||
|
|
||||||
publicScope.shouldDropStatus = function () {
|
|
||||||
return (Math.round(Math.random()*100) < (privateScope.dropRatio * privateScope.statusDropFactor));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method return periodic for polling interval that should populate queue in 80% or less
|
* This method return periodic for polling interval that should populate queue in 80% or less
|
||||||
* @param {number} requestedInterval
|
* @param {number} requestedInterval
|
||||||
|
@ -317,6 +306,10 @@ var mspQueue = function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
publicScope.getQueue = function () {
|
||||||
|
return privateScope.queue;
|
||||||
|
};
|
||||||
|
|
||||||
setInterval(publicScope.executor, Math.round(1000 / privateScope.handlerFrequency));
|
setInterval(publicScope.executor, Math.round(1000 / privateScope.handlerFrequency));
|
||||||
setInterval(publicScope.balancer, Math.round(1000 / privateScope.balancerFrequency));
|
setInterval(publicScope.balancer, Math.round(1000 / privateScope.balancerFrequency));
|
||||||
|
|
||||||
|
|
27
js/sitl.js
27
js/sitl.js
|
@ -65,7 +65,14 @@ var Ser2TCP = {
|
||||||
if (err)
|
if (err)
|
||||||
console.log(err);
|
console.log(err);
|
||||||
});
|
});
|
||||||
|
} else if (GUI.operating_system == 'MacOS') {
|
||||||
|
path = './../resources/sitl/macos/Ser2TCP'
|
||||||
|
chmod(path, 0o755, (err) => {
|
||||||
|
if (err)
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
|
alert(GUI.operating_system);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,12 +145,13 @@ var Ser2TCP = {
|
||||||
if (m)
|
if (m)
|
||||||
devices.push(m[0]);
|
devices.push(m[0]);
|
||||||
} else {
|
} else {
|
||||||
if (device.displayName != null) {
|
/* Limit to: USB serial, RFCOMM (BT), 6 legacy devices */
|
||||||
var m = device.path.match(/\/dev\/.*/)
|
if (device.pnpId ||
|
||||||
if (m)
|
device.path.match(/rfcomm\d*/) ||
|
||||||
devices.push(m[0]);
|
device.path.match(/ttyS[0-5]$/)) {
|
||||||
|
devices.push(device.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
callback(devices);
|
callback(devices);
|
||||||
|
@ -217,7 +225,16 @@ var SITLProcess = {
|
||||||
if (err)
|
if (err)
|
||||||
console.log(err);
|
console.log(err);
|
||||||
});
|
});
|
||||||
|
} else if (GUI.operating_system == 'MacOS') {
|
||||||
|
sitlExePath = path.join(__dirname, './../resources/sitl/macos/inav_SITL');
|
||||||
|
eepromPath = `${app.getPath('userData')}/${eepromFileName}`
|
||||||
|
chmod(sitlExePath, 0o755, err => {
|
||||||
|
if (err)
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
alert(GUI.operating_system);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
const ol = require('openlayers');
|
const ol = require('openlayers');
|
||||||
|
|
||||||
const MWNP = require('./mwnp');
|
const MWNP = require('./mwnp');
|
||||||
|
const Waypoint = require('./waypoint');
|
||||||
const BitHelper = require('./bitHelper');
|
const BitHelper = require('./bitHelper');
|
||||||
|
|
||||||
let WaypointCollection = function () {
|
let WaypointCollection = function () {
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
"@electron-forge/maker-zip": "^7.2.0",
|
"@electron-forge/maker-zip": "^7.2.0",
|
||||||
"@electron-forge/maker-dmg": "^7.2.0",
|
"@electron-forge/maker-dmg": "^7.2.0",
|
||||||
"@electron-forge/maker-wix": "^7.2.0",
|
"@electron-forge/maker-wix": "^7.2.0",
|
||||||
"electron": "28.1.4"
|
"electron": "28.1.4",
|
||||||
|
"node-gyp": "^10.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
resources/sitl/macos/Ser2TCP
Executable file
BIN
resources/sitl/macos/Ser2TCP
Executable file
Binary file not shown.
BIN
resources/sitl/macos/inav_SITL
Executable file
BIN
resources/sitl/macos/inav_SITL
Executable file
Binary file not shown.
|
@ -6,12 +6,10 @@ const wNumb = require('wnumb/wNumb')
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
const mspQueue = require('./../js/serial_queue');
|
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
const FC = require('./../js/fc');
|
const FC = require('./../js/fc');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const i18n = require('./../js/localization');
|
const i18n = require('./../js/localization');
|
||||||
|
const interval = require('./../js/intervals');
|
||||||
|
|
||||||
TABS.adjustments = {};
|
TABS.adjustments = {};
|
||||||
|
|
||||||
|
@ -260,11 +258,6 @@ TABS.adjustments.initialize = function (callback) {
|
||||||
|
|
||||||
// data pulling functions used inside interval timer
|
// data pulling functions used inside interval timer
|
||||||
function get_rc_data() {
|
function get_rc_data() {
|
||||||
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_RC, false, false, update_ui);
|
MSP.send_message(MSPCodes.MSP_RC, false, false, update_ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +273,7 @@ TABS.adjustments.initialize = function (callback) {
|
||||||
update_ui();
|
update_ui();
|
||||||
|
|
||||||
// enable data pulling
|
// enable data pulling
|
||||||
mspBalancedInterval.add('aux_data_pull', 50, 1, get_rc_data);
|
interval.add('aux_data_pull', get_rc_data, 50);
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
GUI.content_ready(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,11 @@ const store = new Store();
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
const mspQueue = require('./../js/serial_queue');
|
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
const FC = require('./../js/fc');
|
const FC = require('./../js/fc');
|
||||||
const adjustBoxNameIfPeripheralWithModeID = require('./../js/peripherals');
|
const adjustBoxNameIfPeripheralWithModeID = require('./../js/peripherals');
|
||||||
const i18n = require('./../js/localization');
|
const i18n = require('./../js/localization');
|
||||||
|
const interval = require('./../js/intervals');
|
||||||
|
|
||||||
var ORIG_AUX_CONFIG_IDS = [];
|
var ORIG_AUX_CONFIG_IDS = [];
|
||||||
|
|
||||||
|
@ -375,11 +373,6 @@ TABS.auxiliary.initialize = function (callback) {
|
||||||
|
|
||||||
// data pulling functions used inside interval timer
|
// data pulling functions used inside interval timer
|
||||||
function get_rc_data() {
|
function get_rc_data() {
|
||||||
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_RC, false, false, update_ui);
|
MSP.send_message(MSPCodes.MSP_RC, false, false, update_ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +509,7 @@ TABS.auxiliary.initialize = function (callback) {
|
||||||
update_ui();
|
update_ui();
|
||||||
|
|
||||||
// enable data pulling
|
// enable data pulling
|
||||||
mspBalancedInterval.add('aux_data_pull', 50, 1, get_rc_data);
|
interval.add('aux_data_pull', get_rc_data, 50);
|
||||||
|
|
||||||
$(".tab-auxiliary .acroEnabled").width($("#mode-0 .info").width());
|
$(".tab-auxiliary .acroEnabled").width($("#mode-0 .info").width());
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
const { dialog } = require("@electron/remote");
|
const { dialog } = require("@electron/remote");
|
||||||
|
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
|
@ -13,6 +14,7 @@ const { globalSettings } = require('./../js/globalSettings');
|
||||||
const CliAutoComplete = require('./../js/CliAutoComplete');
|
const CliAutoComplete = require('./../js/CliAutoComplete');
|
||||||
const { ConnectionType } = require('./../js/connection/connection');
|
const { ConnectionType } = require('./../js/connection/connection');
|
||||||
const jBox = require('./../js/libraries/jBox/jBox.min');
|
const jBox = require('./../js/libraries/jBox/jBox.min');
|
||||||
|
const mspDeduplicationQueue = require('./msp/mspDeduplicationQueue');
|
||||||
|
|
||||||
TABS.cli = {
|
TABS.cli = {
|
||||||
lineDelayMs: 50,
|
lineDelayMs: 50,
|
||||||
|
@ -94,6 +96,7 @@ TABS.cli.initialize = function (callback) {
|
||||||
|
|
||||||
// Flush MSP queue as well as all MSP registered callbacks
|
// Flush MSP queue as well as all MSP registered callbacks
|
||||||
mspQueue.flush();
|
mspQueue.flush();
|
||||||
|
mspDeduplicationQueue.flush();
|
||||||
MSP.callbacks_cleanup();
|
MSP.callbacks_cleanup();
|
||||||
|
|
||||||
self.outputHistory = "";
|
self.outputHistory = "";
|
||||||
|
@ -170,7 +173,6 @@ TABS.cli.initialize = function (callback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
fs.writeFile(result.filePath, self.outputHistory, (err) => {
|
fs.writeFile(result.filePath, self.outputHistory, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
GUI.log(i18n.getMessage('ErrorWritingFile'));
|
GUI.log(i18n.getMessage('ErrorWritingFile'));
|
||||||
|
@ -255,7 +257,6 @@ TABS.cli.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.filePaths.length == 1) {
|
if (result.filePaths.length == 1) {
|
||||||
const fs = require('fs');
|
|
||||||
fs.readFile(result.filePaths[0], (err, data) => {
|
fs.readFile(result.filePaths[0], (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
GUI.log(i18n.getMessage('ErrorReadingFile'));
|
GUI.log(i18n.getMessage('ErrorReadingFile'));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { marked } = require('marked');
|
const { marked } = require('marked');
|
||||||
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const semver = require('semver');
|
const semver = require('semver');
|
||||||
const { dialog } = require('@electron/remote');
|
const { dialog } = require('@electron/remote');
|
||||||
|
@ -17,11 +18,11 @@ const CONFIGURATOR = require('./../js/data_storage');
|
||||||
const SerialBackend = require('./../js/serial_backend');
|
const SerialBackend = require('./../js/serial_backend');
|
||||||
const timeout = require('./../js/timeouts');
|
const timeout = require('./../js/timeouts');
|
||||||
const interval = require('./../js/intervals');
|
const interval = require('./../js/intervals');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const mspQueue = require('./../js/serial_queue');
|
const mspQueue = require('./../js/serial_queue');
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const STM32 = require('./../js/protocols/stm32');
|
const STM32 = require('./../js/protocols/stm32');
|
||||||
const STM32DFU = require('./../js/protocols/stm32usbdfu');
|
const STM32DFU = require('./../js/protocols/stm32usbdfu');
|
||||||
|
const mspDeduplicationQueue = require('./msp/mspDeduplicationQueue');
|
||||||
|
|
||||||
TABS.firmware_flasher = {};
|
TABS.firmware_flasher = {};
|
||||||
TABS.firmware_flasher.initialize = function (callback) {
|
TABS.firmware_flasher.initialize = function (callback) {
|
||||||
|
@ -255,8 +256,6 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
filename = result.filePaths[0];
|
filename = result.filePaths[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
$('div.git_info').slideUp();
|
$('div.git_info').slideUp();
|
||||||
|
|
||||||
console.log('Loading file from: ' + filename);
|
console.log('Loading file from: ' + filename);
|
||||||
|
@ -774,12 +773,12 @@ TABS.firmware_flasher.onValidFirmware = function() {
|
||||||
|
|
||||||
TABS.firmware_flasher.closeTempConnection = function() {
|
TABS.firmware_flasher.closeTempConnection = function() {
|
||||||
timeout.killAll();
|
timeout.killAll();
|
||||||
interval.killAll(['global_data_refresh', 'msp-load-update']);
|
interval.killAll(['global_data_refresh', 'msp-load-update', 'ltm-connection-check']);
|
||||||
mspBalancedInterval.flush();
|
|
||||||
|
|
||||||
mspQueue.flush();
|
mspQueue.flush();
|
||||||
mspQueue.freeHardLock();
|
mspQueue.freeHardLock();
|
||||||
mspQueue.freeSoftLock();
|
mspQueue.freeSoftLock();
|
||||||
|
mspDeduplicationQueue.flush();
|
||||||
CONFIGURATOR.connection.emptyOutputBuffer();
|
CONFIGURATOR.connection.emptyOutputBuffer();
|
||||||
|
|
||||||
CONFIGURATOR.connectionValid = false;
|
CONFIGURATOR.connectionValid = false;
|
||||||
|
|
12
tabs/gps.js
12
tabs/gps.js
|
@ -8,8 +8,7 @@ const MSPChainerClass = require('./../js/msp/MSPchainer');
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
const interval = require('./../js/intervals');
|
||||||
const mspQueue = require('./../js/serial_queue');
|
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
const FC = require('./../js/fc');
|
const FC = require('./../js/fc');
|
||||||
const i18n = require('./../js/localization');
|
const i18n = require('./../js/localization');
|
||||||
|
@ -262,7 +261,6 @@ TABS.gps.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_ui() {
|
function update_ui() {
|
||||||
|
|
||||||
let lat = FC.GPS_DATA.lat / 10000000;
|
let lat = FC.GPS_DATA.lat / 10000000;
|
||||||
let lon = FC.GPS_DATA.lon / 10000000;
|
let lon = FC.GPS_DATA.lon / 10000000;
|
||||||
|
|
||||||
|
@ -400,19 +398,15 @@ TABS.gps.initialize = function (callback) {
|
||||||
* enable data pulling
|
* enable data pulling
|
||||||
* GPS is usually refreshed at 5Hz, there is no reason to pull it much more often, really...
|
* GPS is usually refreshed at 5Hz, there is no reason to pull it much more often, really...
|
||||||
*/
|
*/
|
||||||
mspBalancedInterval.add('gps_pull', 200, 3, function gps_update() {
|
interval.add('gps_pull', function gps_update() {
|
||||||
// avoid usage of the GPS commands until a GPS sensor is detected for targets that are compiled without GPS support.
|
// avoid usage of the GPS commands until a GPS sensor is detected for targets that are compiled without GPS support.
|
||||||
if (!SerialBackend.have_sensor(FC.CONFIG.activeSensors, 'gps')) {
|
if (!SerialBackend.have_sensor(FC.CONFIG.activeSensors, 'gps')) {
|
||||||
update_ui();
|
update_ui();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_raw_gps_data();
|
get_raw_gps_data();
|
||||||
});
|
}, 200);
|
||||||
|
|
||||||
|
|
||||||
$('a.save').on('click', function () {
|
$('a.save').on('click', function () {
|
||||||
|
|
|
@ -230,9 +230,8 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
||||||
|
|
||||||
$('.colors').on('dblclick', 'button', function(e) {
|
$('.colors').on('dblclick', 'button', function(e) {
|
||||||
|
|
||||||
var pp = $('.tab-led-strip').position();
|
var moveLeft = $('.tab-led-strip').offset().left + ($('.colorDefineSliders').width() / 2);
|
||||||
var moveLeft = $('.tab-led-strip').position().left + ($('.colorDefineSliders').width() / 2);
|
var moveUp = $('.tab-led-strip').offset().top + $('.colorDefineSliders').height() + 20;
|
||||||
var moveUp = $('.tab-led-strip').position().top + $('.colorDefineSliders').height() + 20;
|
|
||||||
|
|
||||||
$('.colorDefineSliders').css('left', e.pageX - e.offsetX - moveLeft);
|
$('.colorDefineSliders').css('left', e.pageX - e.offsetX - moveLeft);
|
||||||
$('.colorDefineSliders').css('top', e.pageY - e.offsetY - moveUp);
|
$('.colorDefineSliders').css('top', e.pageY - e.offsetY - moveUp);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
const { dialog } = require("@electron/remote");
|
const { dialog } = require("@electron/remote");
|
||||||
const Store = require('electron-store');
|
const Store = require('electron-store');
|
||||||
const store = new Store();
|
const store = new Store();
|
||||||
|
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
const FC = require('./../js/fc');
|
const FC = require('./../js/fc');
|
||||||
const CONFIGURATOR = require('./../js/data_storage');
|
const CONFIGURATOR = require('./../js/data_storage');
|
||||||
|
@ -84,7 +84,6 @@ TABS.logging.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
interval.add('log_data_poll', log_data_poll, parseInt($('select.speed').val()), true); // refresh rate goes here
|
interval.add('log_data_poll', log_data_poll, parseInt($('select.speed').val()), true); // refresh rate goes here
|
||||||
const fs = require('fs');
|
|
||||||
interval.add('write_data', function write_data() {
|
interval.add('write_data', function write_data() {
|
||||||
if (log_buffer.length && readyToWrite) { // only execute when there is actual data to write
|
if (log_buffer.length && readyToWrite) { // only execute when there is actual data to write
|
||||||
|
|
||||||
|
@ -105,8 +104,7 @@ TABS.logging.initialize = function (callback) {
|
||||||
GUI.log(i18n.getMessage('loggingErrorOneProperty'));
|
GUI.log(i18n.getMessage('loggingErrorOneProperty'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
interval.killAll(['global_data_refresh', 'msp-load-update']);
|
interval.killAll(['global_data_refresh', 'msp-load-update', 'ltm-connection-check']);
|
||||||
mspBalancedInterval.flush();
|
|
||||||
|
|
||||||
$('.speed').prop('disabled', false);
|
$('.speed').prop('disabled', false);
|
||||||
$(this).text(i18n.getMessage('loggingStart'));
|
$(this).text(i18n.getMessage('loggingStart'));
|
||||||
|
|
|
@ -6,12 +6,11 @@ const MSPChainerClass = require('./../js/msp/MSPchainer');
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const mspQueue = require('./../js/serial_queue');
|
|
||||||
const FC = require('./../js/fc');
|
const FC = require('./../js/fc');
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
const i18n = require('./../js/localization');
|
const i18n = require('./../js/localization');
|
||||||
const { mixer } = require('./../js/model');
|
const { mixer } = require('./../js/model');
|
||||||
|
const interval = require('./../js/intervals');
|
||||||
|
|
||||||
TABS.magnetometer = {};
|
TABS.magnetometer = {};
|
||||||
|
|
||||||
|
@ -524,9 +523,6 @@ TABS.magnetometer.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function get_fast_data() {
|
function get_fast_data() {
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_ATTITUDE, false, false, function () {
|
MSP.send_message(MSPCodes.MSP_ATTITUDE, false, false, function () {
|
||||||
self.roll_e.text(i18n.getMessage('initialSetupAttitude', [FC.SENSOR_DATA.kinematics[0]]));
|
self.roll_e.text(i18n.getMessage('initialSetupAttitude', [FC.SENSOR_DATA.kinematics[0]]));
|
||||||
|
@ -536,7 +532,7 @@ TABS.magnetometer.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mspBalancedInterval.add('setup_data_pull_fast', 40, 1, get_fast_data);
|
interval.add('setup_data_pull_fast', get_fast_data, 40);
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
GUI.content_ready(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
const ol = require('openlayers');
|
const ol = require('openlayers');
|
||||||
|
const xml2js = require('xml2js');
|
||||||
const Store = require('electron-store');
|
const Store = require('electron-store');
|
||||||
const store = new Store();
|
const store = new Store();
|
||||||
const { dialog } = require("@electron/remote");
|
const { dialog } = require("@electron/remote");
|
||||||
|
@ -10,7 +12,6 @@ const MSPChainerClass = require('./../js/msp/MSPchainer');
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const mspQueue = require('./../js/serial_queue');
|
const mspQueue = require('./../js/serial_queue');
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
const FC = require('./../js/fc');
|
const FC = require('./../js/fc');
|
||||||
|
@ -27,6 +28,7 @@ const FwApproachCollection = require('./../js/fwApproachCollection');
|
||||||
const SerialBackend = require('./../js/serial_backend');
|
const SerialBackend = require('./../js/serial_backend');
|
||||||
const { distanceOnLine, wrap_360, calculate_new_cooridatnes } = require('./../js/helpers');
|
const { distanceOnLine, wrap_360, calculate_new_cooridatnes } = require('./../js/helpers');
|
||||||
const Plotly = require('./../js/libraries/plotly-latest.min');
|
const Plotly = require('./../js/libraries/plotly-latest.min');
|
||||||
|
const interval = require('./../js/intervals');
|
||||||
|
|
||||||
var MAX_NEG_FW_LAND_ALT = -2000; // cm
|
var MAX_NEG_FW_LAND_ALT = -2000; // cm
|
||||||
|
|
||||||
|
@ -334,19 +336,15 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
*/
|
*/
|
||||||
if(!isOffline)
|
if(!isOffline)
|
||||||
{
|
{
|
||||||
mspBalancedInterval.add('gps_pull', 200, 3, function gps_update() {
|
interval.add('gps_pull', function gps_update() {
|
||||||
// avoid usage of the GPS commands until a GPS sensor is detected for targets that are compiled without GPS support.
|
// avoid usage of the GPS commands until a GPS sensor is detected for targets that are compiled without GPS support.
|
||||||
if (!SerialBackend.have_sensor(FC.CONFIG.activeSensors, 'gps')) {
|
if (!SerialBackend.have_sensor(FC.CONFIG.activeSensors, 'gps')) {
|
||||||
update_gpsTrack();
|
update_gpsTrack();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_raw_gps_data();
|
get_raw_gps_data();
|
||||||
});
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
GUI.content_ready(callback);
|
||||||
|
@ -483,7 +481,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
function checkApproachAltitude(altitude, isSeaLevelRef, sealevel) {
|
function checkApproachAltitude(altitude, isSeaLevelRef, sealevel) {
|
||||||
|
|
||||||
if (altitude - (isSeaLevelRef ? sealevel * 100 : 0 ) < 0) {
|
if (altitude - (isSeaLevelRef ? sealevel * 100 : 0 ) < 0) {
|
||||||
alert(i18n.getMessage('MissionPlannerAltitudeChangeReset'));
|
GUI.alert(i18n.getMessage('MissionPlannerAltitudeChangeReset'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +491,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
function checkLandingAltitude(altitude, isSeaLevelRef, sealevel) {
|
function checkLandingAltitude(altitude, isSeaLevelRef, sealevel) {
|
||||||
|
|
||||||
if (altitude - (isSeaLevelRef ? sealevel * 100 : 0 ) < MAX_NEG_FW_LAND_ALT) {
|
if (altitude - (isSeaLevelRef ? sealevel * 100 : 0 ) < MAX_NEG_FW_LAND_ALT) {
|
||||||
alert(i18n.getMessage('MissionPlannerFwLAndingAltitudeChangeReset'));
|
GUI.alert(i18n.getMessage('MissionPlannerFwLAndingAltitudeChangeReset'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1202,15 +1200,15 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
// If one is POI, draw orange line in-between and modulate dashline each time a new POI is defined
|
// If one is POI, draw orange line in-between and modulate dashline each time a new POI is defined
|
||||||
else if (typeof oldPos !== 'undefined' && activatePoi == true && activateHead != true) {
|
else if (typeof oldPos !== 'undefined' && activatePoi == true && activateHead != true) {
|
||||||
if ((poiList.length % 2) == 0) {
|
if ((poiList.length % 2) == 0) {
|
||||||
paintLine(oldPos, coord, element.getNumber(), color='#ffb725', lineDash=5);
|
paintLine(oldPos, coord, element.getNumber(), '#ffb725', 5);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
paintLine(oldPos, coord, element.getNumber(), color='#ffb725');
|
paintLine(oldPos, coord, element.getNumber(), '#ffb725');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If one is SET_HEAD, draw labelled line in-between with heading value
|
// If one is SET_HEAD, draw labelled line in-between with heading value
|
||||||
else if (typeof oldPos !== 'undefined' && activatePoi != true && activateHead == true) {
|
else if (typeof oldPos !== 'undefined' && activatePoi != true && activateHead == true) {
|
||||||
paintLine(oldPos, coord, element.getNumber(), color='#1497f1', lineDash=0, lineText=String(oldHeading)+"°");
|
paintLine(oldPos, coord, element.getNumber(), '#1497f1', 0, String(oldHeading)+"°");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.getEndMission() == 0xA5) {
|
if (element.getEndMission() == 0xA5) {
|
||||||
|
@ -1227,7 +1225,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
if (element.getAction() == MWNP.WPTYPE.JUMP) {
|
if (element.getAction() == MWNP.WPTYPE.JUMP) {
|
||||||
let jumpWPIndex = multiMissionWPNum + element.getP1();
|
let jumpWPIndex = multiMissionWPNum + element.getP1();
|
||||||
let coord = ol.proj.fromLonLat([mission.getWaypoint(jumpWPIndex).getLonMap(), mission.getWaypoint(jumpWPIndex).getLatMap()]);
|
let coord = ol.proj.fromLonLat([mission.getWaypoint(jumpWPIndex).getLonMap(), mission.getWaypoint(jumpWPIndex).getLatMap()]);
|
||||||
paintLine(oldPos, coord, element.getNumber(), color='#e935d6', lineDash=5, lineText="Repeat x"+(element.getP2() == -1 ? " infinite" : String(element.getP2())), selection=false, arrow=true);
|
paintLine(oldPos, coord, element.getNumber(), '#e935d6', 5, "Repeat x"+(element.getP2() == -1 ? " infinite" : String(element.getP2())), false, true);
|
||||||
}
|
}
|
||||||
// If classic WPs is defined with a heading = -1, change Boolean for POI to false. If it is defined with a value different from -1, activate Heading boolean
|
// If classic WPs is defined with a heading = -1, change Boolean for POI to false. If it is defined with a value different from -1, activate Heading boolean
|
||||||
else if (element.getAction() == MWNP.WPTYPE.SET_HEAD) {
|
else if (element.getAction() == MWNP.WPTYPE.SET_HEAD) {
|
||||||
|
@ -1489,26 +1487,26 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
if ($(this).val() >= 360 || ($(this).val() < 0 && $(this).val() != -1))
|
if ($(this).val() >= 360 || ($(this).val() < 0 && $(this).val() != -1))
|
||||||
{
|
{
|
||||||
$(this).val(-1);
|
$(this).val(-1);
|
||||||
alert(i18n.getMessage('MissionPlannerHeadSettingsCheck'));
|
GUI.alert(i18n.getMessage('MissionPlannerHeadSettingsCheck'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (MWNP.WPTYPE.REV[element.getAction()] == "RTH") {
|
else if (MWNP.WPTYPE.REV[element.getAction()] == "RTH") {
|
||||||
if ($(this).val() != 0 && $(this).val() != 1)
|
if ($(this).val() != 0 && $(this).val() != 1)
|
||||||
{
|
{
|
||||||
$(this).val(0);
|
$(this).val(0);
|
||||||
alert(i18n.getMessage('MissionPlannerRTHSettingsCheck'));
|
GUI.alert(i18n.getMessage('MissionPlannerRTHSettingsCheck'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (MWNP.WPTYPE.REV[element.getAction()] == "JUMP") {
|
else if (MWNP.WPTYPE.REV[element.getAction()] == "JUMP") {
|
||||||
if ($(this).val() > mission.getNonAttachedList().length || $(this).val() < 1)
|
if ($(this).val() > mission.getNonAttachedList().length || $(this).val() < 1)
|
||||||
{
|
{
|
||||||
$(this).val(1);
|
$(this).val(1);
|
||||||
alert(i18n.getMessage('MissionPlannerJumpSettingsCheck'));
|
GUI.alert(i18n.getMessage('MissionPlannerJumpSettingsCheck'));
|
||||||
}
|
}
|
||||||
else if (mission.getPoiList().length != 0 && mission.getPoiList()) {
|
else if (mission.getPoiList().length != 0 && mission.getPoiList()) {
|
||||||
if (mission.getPoiList().includes(mission.convertJumpNumberToWaypoint(Number($(this).val())-1))) {
|
if (mission.getPoiList().includes(mission.convertJumpNumberToWaypoint(Number($(this).val())-1))) {
|
||||||
$(this).val(1);
|
$(this).val(1);
|
||||||
alert(i18n.getMessage('MissionPlannerJump3SettingsCheck'));
|
GUI.alert(i18n.getMessage('MissionPlannerJump3SettingsCheck'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1523,7 +1521,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
if ($(this).val() > 10 || ($(this).val() < 0 && $(this).val() != -1))
|
if ($(this).val() > 10 || ($(this).val() < 0 && $(this).val() != -1))
|
||||||
{
|
{
|
||||||
$(this).val(0);
|
$(this).val(0);
|
||||||
alert(i18n.getMessage('MissionPlannerJump2SettingsCheck'));
|
GUI.alert(i18n.getMessage('MissionPlannerJump2SettingsCheck'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
element.setP2(Number($(this).val()));
|
element.setP2(Number($(this).val()));
|
||||||
|
@ -2310,7 +2308,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
let found = false;
|
let found = false;
|
||||||
mission.get().forEach(wp => {
|
mission.get().forEach(wp => {
|
||||||
if (wp.getAction() == MWNP.WPTYPE.LAND) {
|
if (wp.getAction() == MWNP.WPTYPE.LAND) {
|
||||||
alert(i18n.getMessage('MissionPlannerOnlyOneLandWp'));
|
GUI.alert(i18n.getMessage('MissionPlannerOnlyOneLandWp'));
|
||||||
found = true;
|
found = true;
|
||||||
$(event.currentTarget).val(selectedMarker.getAction());
|
$(event.currentTarget).val(selectedMarker.getAction());
|
||||||
}
|
}
|
||||||
|
@ -2684,7 +2682,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
|
|
||||||
$('#addSafehome').on('click', () => {
|
$('#addSafehome').on('click', () => {
|
||||||
if (FC.SAFEHOMES.safehomeCount() + 1 > FC.SAFEHOMES.getMaxSafehomeCount()){
|
if (FC.SAFEHOMES.safehomeCount() + 1 > FC.SAFEHOMES.getMaxSafehomeCount()){
|
||||||
alert(i18n.getMessage('missionSafehomeMaxSafehomesReached'));
|
GUI.alert(i18n.getMessage('missionSafehomeMaxSafehomesReached'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3016,7 +3014,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
$('#removePoint').on('click', function () {
|
$('#removePoint').on('click', function () {
|
||||||
if (selectedMarker) {
|
if (selectedMarker) {
|
||||||
if (mission.isJumpTargetAttached(selectedMarker)) {
|
if (mission.isJumpTargetAttached(selectedMarker)) {
|
||||||
alert(i18n.getMessage('MissionPlannerJumpTargetRemoval'));
|
GUI.alert(i18n.getMessage('MissionPlannerJumpTargetRemoval'));
|
||||||
}
|
}
|
||||||
else if (mission.getAttachedFromWaypoint(selectedMarker) && mission.getAttachedFromWaypoint(selectedMarker).length != 0) {
|
else if (mission.getAttachedFromWaypoint(selectedMarker) && mission.getAttachedFromWaypoint(selectedMarker).length != 0) {
|
||||||
if (confirm(i18n.getMessage('confirm_delete_point_with_options'))) {
|
if (confirm(i18n.getMessage('confirm_delete_point_with_options'))) {
|
||||||
|
@ -3096,7 +3094,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
|
|
||||||
$('#saveMissionButton').on('click', function () {
|
$('#saveMissionButton').on('click', function () {
|
||||||
if (mission.isEmpty()) {
|
if (mission.isEmpty()) {
|
||||||
alert(i18n.getMessage('no_waypoints_to_save'));
|
GUI.alert(i18n.getMessage('no_waypoints_to_save'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$(this).addClass('disabled');
|
$(this).addClass('disabled');
|
||||||
|
@ -3115,7 +3113,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
|
|
||||||
$('#saveEepromMissionButton').on('click', function () {
|
$('#saveEepromMissionButton').on('click', function () {
|
||||||
if (mission.isEmpty()) {
|
if (mission.isEmpty()) {
|
||||||
alert(i18n.getMessage('no_waypoints_to_save'));
|
GUI.alert(i18n.getMessage('no_waypoints_to_save'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$(this).addClass('disabled');
|
$(this).addClass('disabled');
|
||||||
|
@ -3161,9 +3159,6 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
//
|
//
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
function loadMissionFile(filename) {
|
function loadMissionFile(filename) {
|
||||||
const fs = require('fs');
|
|
||||||
if (!window.xml2js) return GUI.log(i18n.getMessage('errorReadingFileXml2jsNotFound'));
|
|
||||||
|
|
||||||
for (let i = FC.SAFEHOMES.getMaxSafehomeCount(); i < FC.FW_APPROACH.getMaxFwApproachCount(); i++) {
|
for (let i = FC.SAFEHOMES.getMaxSafehomeCount(); i < FC.FW_APPROACH.getMaxFwApproachCount(); i++) {
|
||||||
FC.FW_APPROACH.clean(i);
|
FC.FW_APPROACH.clean(i);
|
||||||
}
|
}
|
||||||
|
@ -3174,7 +3169,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
return console.error(err);
|
return console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.xml2js.Parser({ 'explicitChildren': true, 'preserveChildrenOrder': true }).parseString(data, (err, result) => {
|
xml2js.Parser({ 'explicitChildren': true, 'preserveChildrenOrder': true }).parseString(data, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
GUI.log(i18n.getMessage('errorParsingFile'));
|
GUI.log(i18n.getMessage('errorParsingFile'));
|
||||||
return console.error(err);
|
return console.error(err);
|
||||||
|
@ -3344,9 +3339,6 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveMissionFile(filename) {
|
function saveMissionFile(filename) {
|
||||||
const fs = require('fs');
|
|
||||||
if (!window.xml2js) return GUI.log(i18n.getMessage('errorWritingFileXml2jsNotFound'));
|
|
||||||
|
|
||||||
var center = ol.proj.toLonLat(map.getView().getCenter());
|
var center = ol.proj.toLonLat(map.getView().getCenter());
|
||||||
var zoom = map.getView().getZoom();
|
var zoom = map.getView().getZoom();
|
||||||
let multimission = multimissionCount && !singleMissionActive();
|
let multimission = multimissionCount && !singleMissionActive();
|
||||||
|
@ -3408,7 +3400,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
approachIdx++;
|
approachIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var builder = new window.xml2js.Builder({ 'rootName': 'mission', 'renderOpts': { 'pretty': true, 'indent': '\t', 'newline': '\n' } });
|
var builder = new xml2js.Builder({ 'rootName': 'mission', 'renderOpts': { 'pretty': true, 'indent': '\t', 'newline': '\n' } });
|
||||||
var xml = builder.buildObject(data);
|
var xml = builder.buildObject(data);
|
||||||
xml = xml.replace(/missionitem mission/g, 'meta mission');
|
xml = xml.replace(/missionitem mission/g, 'meta mission');
|
||||||
fs.writeFile(filename, xml, (err) => {
|
fs.writeFile(filename, xml, (err) => {
|
||||||
|
@ -3445,7 +3437,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
$('#loadMissionButton').removeClass('disabled');
|
$('#loadMissionButton').removeClass('disabled');
|
||||||
}
|
}
|
||||||
if (!FC.MISSION_PLANNER.getCountBusyPoints()) {
|
if (!FC.MISSION_PLANNER.getCountBusyPoints()) {
|
||||||
alert(i18n.getMessage('no_waypoints_to_load'));
|
GUI.alert(i18n.getMessage('no_waypoints_to_load'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mission.reinit();
|
mission.reinit();
|
||||||
|
@ -3555,7 +3547,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
if (AbsAltCheck) {
|
if (AbsAltCheck) {
|
||||||
if (checkAltitude < 100 * elevation) {
|
if (checkAltitude < 100 * elevation) {
|
||||||
if (resetAltitude) {
|
if (resetAltitude) {
|
||||||
alert(i18n.getMessage('MissionPlannerAltitudeChangeReset'));
|
GUI.alert(i18n.getMessage('MissionPlannerAltitudeChangeReset'));
|
||||||
altitude = selectedMarker.getAlt();
|
altitude = selectedMarker.getAlt();
|
||||||
} else {
|
} else {
|
||||||
altitude = settings.alt + 100 * elevation;
|
altitude = settings.alt + 100 * elevation;
|
||||||
|
@ -3566,7 +3558,7 @@ TABS.mission_control.initialize = function (callback) {
|
||||||
let elevationAtHome = HOME.getAlt();
|
let elevationAtHome = HOME.getAlt();
|
||||||
if ((checkAltitude / 100 + elevationAtHome) < elevation) {
|
if ((checkAltitude / 100 + elevationAtHome) < elevation) {
|
||||||
if (resetAltitude) {
|
if (resetAltitude) {
|
||||||
alert(i18n.getMessage('MissionPlannerAltitudeChangeReset'));
|
GUI.alert(i18n.getMessage('MissionPlannerAltitudeChangeReset'));
|
||||||
altitude = selectedMarker.getAlt();
|
altitude = selectedMarker.getAlt();
|
||||||
} else {
|
} else {
|
||||||
let currentGroundClearance = 100 * Number($('#groundClearanceValueAtWP').text());
|
let currentGroundClearance = 100 * Number($('#groundClearanceValueAtWP').text());
|
||||||
|
@ -3702,9 +3694,9 @@ TABS.mission_control.setBit = function(bits, bit, value) {
|
||||||
|
|
||||||
// function handleError(evt) {
|
// function handleError(evt) {
|
||||||
// if (evt.message) { // Chrome sometimes provides this
|
// if (evt.message) { // Chrome sometimes provides this
|
||||||
// alert("error: "+evt.message +" at linenumber: "+evt.lineno+" of file: "+evt.filename);
|
// GUI.alert("error: "+evt.message +" at linenumber: "+evt.lineno+" of file: "+evt.filename);
|
||||||
// } else {
|
// } else {
|
||||||
// alert("error: "+evt.type+" from element: "+(evt.srcElement || evt.target));
|
// GUI.alert("error: "+evt.type+" from element: "+(evt.srcElement || evt.target));
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ const FC = require('./../js/fc');
|
||||||
const i18n = require('./../js/localization');
|
const i18n = require('./../js/localization');
|
||||||
const { mixer, platform, PLATFORM, INPUT, STABILIZED } = require('./../js/model');
|
const { mixer, platform, PLATFORM, INPUT, STABILIZED } = require('./../js/model');
|
||||||
const Settings = require('./../js/settings');
|
const Settings = require('./../js/settings');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const jBox = require('../js/libraries/jBox/jBox.min');
|
const jBox = require('../js/libraries/jBox/jBox.min');
|
||||||
|
const interval = require('./../js/intervals');
|
||||||
|
|
||||||
TABS.mixer = {};
|
TABS.mixer = {};
|
||||||
|
|
||||||
|
@ -823,9 +823,9 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
||||||
|
|
||||||
FC.LOGIC_CONDITIONS.init($('#logic-wrapper'));
|
FC.LOGIC_CONDITIONS.init($('#logic-wrapper'));
|
||||||
|
|
||||||
i18n.localize();;
|
i18n.localize();;
|
||||||
|
|
||||||
mspBalancedInterval.add('logic_conditions_pull', 350, 1, getLogicConditionsStatus);
|
interval.add('logic_conditions_pull', getLogicConditionsStatus, 350);
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
GUI.content_ready(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,6 @@
|
||||||
<div class="legend"></div>
|
<div class="legend"></div>
|
||||||
</li>
|
</li>
|
||||||
</ul><bbr />
|
</ul><bbr />
|
||||||
<a class="require-msc-ready regular-button onboardLoggingRebootMsc" href="#" i18n="cliMscBtn"></a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const { dialog } = require("@electron/remote");
|
||||||
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
|
const mspHelper = require("./../js/msp/MSPHelper");
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
const FC = require('./../js/fc');
|
const FC = require('./../js/fc');
|
||||||
const CONFIGURATOR = require('./../js/data_storage');
|
const CONFIGURATOR = require('./../js/data_storage');
|
||||||
|
@ -355,7 +358,6 @@ TABS.onboard_logging.initialize = function (callback) {
|
||||||
const maxBytes = FC.DATAFLASH.usedSize;
|
const maxBytes = FC.DATAFLASH.usedSize;
|
||||||
|
|
||||||
prepare_file(function(filename) {
|
prepare_file(function(filename) {
|
||||||
const fs = require('fs');
|
|
||||||
let nextAddress = 0;
|
let nextAddress = 0;
|
||||||
|
|
||||||
show_saving_dialog();
|
show_saving_dialog();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const inflection = require( 'inflection' );
|
const inflection = require( 'inflection' );
|
||||||
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const semver = require('semver');
|
const semver = require('semver');
|
||||||
const mapSeries = require('promise-map-series');
|
const mapSeries = require('promise-map-series');
|
||||||
|
@ -269,7 +270,6 @@ FONT.openFontFile = function ($preview) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.filePaths.length == 1) {
|
if (result.filePaths.length == 1) {
|
||||||
const fs = require('fs');
|
|
||||||
const fontData = fs.readFileSync(result.filePaths[0], {flag: "r"});
|
const fontData = fs.readFileSync(result.filePaths[0], {flag: "r"});
|
||||||
FONT.parseMCMFontFile(fontData.toString());
|
FONT.parseMCMFontFile(fontData.toString());
|
||||||
resolve();
|
resolve();
|
||||||
|
|
|
@ -5,7 +5,6 @@ const path = require('path');
|
||||||
const MSPChainerClass = require('./../js/msp/MSPchainer');
|
const MSPChainerClass = require('./../js/msp/MSPchainer');
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const mspQueue = require('./../js/serial_queue')
|
const mspQueue = require('./../js/serial_queue')
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
|
@ -429,19 +428,9 @@ TABS.outputs.initialize = function (callback) {
|
||||||
$voltageHelper = $(".current-voltage");
|
$voltageHelper = $(".current-voltage");
|
||||||
|
|
||||||
// timer initialization
|
// timer initialization
|
||||||
interval.killAll(['motor_and_status_pull', 'global_data_refresh', 'msp-load-update']);
|
interval.killAll(['motor_and_status_pull', 'global_data_refresh', 'msp-load-update', 'ltm-connection-check']);
|
||||||
mspBalancedInterval.flush();
|
|
||||||
|
|
||||||
interval.add('IMU_pull', function () {
|
interval.add('IMU_pull', function () {
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable balancer
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
update_accel_graph();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_RAW_IMU, false, false, update_accel_graph);
|
MSP.send_message(MSPCodes.MSP_RAW_IMU, false, false, update_accel_graph);
|
||||||
}, 25, true);
|
}, 25, true);
|
||||||
|
|
||||||
|
@ -662,21 +651,10 @@ TABS.outputs.initialize = function (callback) {
|
||||||
$motorsEnableTestMode.trigger('change');
|
$motorsEnableTestMode.trigger('change');
|
||||||
|
|
||||||
function getPeriodicMotorOutput() {
|
function getPeriodicMotorOutput() {
|
||||||
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
getPeriodicServoOutput();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_MOTOR, false, false, getPeriodicServoOutput);
|
MSP.send_message(MSPCodes.MSP_MOTOR, false, false, getPeriodicServoOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPeriodicServoOutput() {
|
function getPeriodicServoOutput() {
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
update_ui();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_SERVO, false, false, update_ui);
|
MSP.send_message(MSPCodes.MSP_SERVO, false, false, update_ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,12 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const MSPChainerClass = require('./../js/msp/MSPchainer');
|
const MSPChainerClass = require('./../js/msp/MSPchainer');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
const FC = require('./../js/fc');
|
const FC = require('./../js/fc');
|
||||||
const tabs = require('./../js/tabs');
|
const tabs = require('./../js/tabs');
|
||||||
const i18n = require('./../js/localization');
|
const i18n = require('./../js/localization');
|
||||||
|
const interval = require('./../js/intervals');
|
||||||
|
|
||||||
TABS.programming = {};
|
TABS.programming = {};
|
||||||
|
|
||||||
|
@ -68,9 +67,9 @@ TABS.programming.initialize = function (callback, scrollPosition) {
|
||||||
GUI.log(i18n.getMessage('programmingEepromSaved'));
|
GUI.log(i18n.getMessage('programmingEepromSaved'));
|
||||||
});
|
});
|
||||||
|
|
||||||
mspBalancedInterval.add('logic_conditions_pull', 100, 1, function () {
|
interval.add('logic_conditions_pull', function () {
|
||||||
statusChainer.execute();
|
statusChainer.execute();
|
||||||
});
|
}, 100);
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
GUI.content_ready(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ const path = require('path');
|
||||||
|
|
||||||
const MSPChainerClass = require('./../js/msp/MSPchainer');
|
const MSPChainerClass = require('./../js/msp/MSPchainer');
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const mspQueue = require('./../js/serial_queue');
|
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const MSP = require('./../js/msp');
|
const MSP = require('./../js/msp');
|
||||||
const { GUI, TABS } = require('./../js/gui');
|
const { GUI, TABS } = require('./../js/gui');
|
||||||
|
@ -13,6 +11,7 @@ const FC = require('./../js/fc');
|
||||||
const CONFIGURATOR = require('./../js/data_storage');
|
const CONFIGURATOR = require('./../js/data_storage');
|
||||||
const Settings = require('./../js/settings');
|
const Settings = require('./../js/settings');
|
||||||
const i18n = require('./../js/localization');
|
const i18n = require('./../js/localization');
|
||||||
|
const interval = require('./../js/intervals');
|
||||||
|
|
||||||
TABS.receiver = {
|
TABS.receiver = {
|
||||||
rateChartHeight: 117
|
rateChartHeight: 117
|
||||||
|
@ -370,21 +369,10 @@ TABS.receiver.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function get_rc_data() {
|
function get_rc_data() {
|
||||||
|
|
||||||
/*
|
|
||||||
* Throttling
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
update_ui();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_RC, false, false, update_ui);
|
MSP.send_message(MSPCodes.MSP_RC, false, false, update_ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_ui() {
|
function update_ui() {
|
||||||
var i;
|
|
||||||
|
|
||||||
// update bars with latest data
|
// update bars with latest data
|
||||||
for (let i = 0; i < FC.RC.active_channels; i++) {
|
for (let i = 0; i < FC.RC.active_channels; i++) {
|
||||||
meter_fill_array[i].css('width', ((FC.RC.channels[i] - meter_scale.min) / (meter_scale.max - meter_scale.min) * 100).clamp(0, 100) + '%');
|
meter_fill_array[i].css('width', ((FC.RC.channels[i] - meter_scale.min) / (meter_scale.max - meter_scale.min) * 100).clamp(0, 100) + '%');
|
||||||
|
@ -393,7 +381,7 @@ TABS.receiver.initialize = function (callback) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mspBalancedInterval.add('receiver_pull', 35, 1, get_rc_data);
|
interval.add('receiver_pull', get_rc_data, 25);
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
GUI.content_ready(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -437,95 +437,41 @@ TABS.sensors.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// timer initialization
|
// timer initialization
|
||||||
interval.killAll(['status_pull', 'global_data_refresh', 'msp-load-update']);
|
interval.killAll(['status_pull', 'global_data_refresh', 'msp-load-update', 'ltm-connection-check']);
|
||||||
|
|
||||||
// data pulling timers
|
// data pulling timers
|
||||||
if (checkboxes[0] || checkboxes[1] || checkboxes[2]) {
|
if (checkboxes[0] || checkboxes[1] || checkboxes[2]) {
|
||||||
interval.add('IMU_pull', function () {
|
interval.add('IMU_pull', function () {
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable balancer
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
update_imu_graphs();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_RAW_IMU, false, false, update_imu_graphs);
|
MSP.send_message(MSPCodes.MSP_RAW_IMU, false, false, update_imu_graphs);
|
||||||
}, fastest, true);
|
}, fastest, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkboxes[3]) {
|
if (checkboxes[3]) {
|
||||||
interval.add('altitude_pull', function altitude_data_pull() {
|
interval.add('altitude_pull', function altitude_data_pull() {
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable balancer
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
update_altitude_graph();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_ALTITUDE, false, false, update_altitude_graph);
|
MSP.send_message(MSPCodes.MSP_ALTITUDE, false, false, update_altitude_graph);
|
||||||
}, rates.baro, true);
|
}, rates.baro, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkboxes[4]) {
|
if (checkboxes[4]) {
|
||||||
interval.add('sonar_pull', function sonar_data_pull() {
|
interval.add('sonar_pull', function sonar_data_pull() {
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable balancer
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
update_sonar_graphs();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_SONAR, false, false, update_sonar_graphs);
|
MSP.send_message(MSPCodes.MSP_SONAR, false, false, update_sonar_graphs);
|
||||||
}, rates.sonar, true);
|
}, rates.sonar, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkboxes[5]) {
|
if (checkboxes[5]) {
|
||||||
interval.add('airspeed_pull', function airspeed_data_pull() {
|
interval.add('airspeed_pull', function airspeed_data_pull() {
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable balancer
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
update_airspeed_graphs();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSPV2_INAV_AIR_SPEED, false, false, update_airspeed_graphs);
|
MSP.send_message(MSPCodes.MSPV2_INAV_AIR_SPEED, false, false, update_airspeed_graphs);
|
||||||
}, rates.airspeed, true);
|
}, rates.airspeed, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkboxes[6]) {
|
if (checkboxes[6]) {
|
||||||
interval.add('temperature_pull', function temperature_data_pull() {
|
interval.add('temperature_pull', function temperature_data_pull() {
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable balancer
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
update_temperature_graphs();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP2_INAV_TEMPERATURES, false, false, update_temperature_graphs);
|
MSP.send_message(MSPCodes.MSP2_INAV_TEMPERATURES, false, false, update_temperature_graphs);
|
||||||
}, 1000, true);
|
}, 1000, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkboxes[7]) {
|
if (checkboxes[7]) {
|
||||||
interval.add('debug_pull', function debug_data_pull() {
|
interval.add('debug_pull', function debug_data_pull() {
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable balancer
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
update_debug_graphs();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP2_INAV_DEBUG, false, false, update_debug_graphs);
|
MSP.send_message(MSPCodes.MSP2_INAV_DEBUG, false, false, update_debug_graphs);
|
||||||
}, rates.debug, true);
|
}, rates.debug, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,7 @@ const MSP = require('./../js/msp');
|
||||||
const MSPCodes = require('./../js/msp/MSPCodes');
|
const MSPCodes = require('./../js/msp/MSPCodes');
|
||||||
const i18n = require('./../js/localization');
|
const i18n = require('./../js/localization');
|
||||||
const mspHelper = require('./../js/msp/MSPHelper');
|
const mspHelper = require('./../js/msp/MSPHelper');
|
||||||
const mspBalancedInterval = require('./../js/msp_balanced_interval');
|
|
||||||
const interval = require('./../js/intervals');
|
const interval = require('./../js/intervals');
|
||||||
const mspQueue = require('./../js/serial_queue');
|
|
||||||
const SerialBackend = require('./../js/serial_backend');
|
const SerialBackend = require('./../js/serial_backend');
|
||||||
const { mixer } = require('./../js/model');
|
const { mixer } = require('./../js/model');
|
||||||
const BitHelper = require('./../js/bitHelper')
|
const BitHelper = require('./../js/bitHelper')
|
||||||
|
@ -119,14 +117,6 @@ TABS.setup.initialize = function (callback) {
|
||||||
|
|
||||||
function get_slow_data() {
|
function get_slow_data() {
|
||||||
if (SerialBackend.have_sensor(FC.CONFIG.activeSensors, 'gps')) {
|
if (SerialBackend.have_sensor(FC.CONFIG.activeSensors, 'gps')) {
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable balancer
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_RAW_GPS, false, false, function () {
|
MSP.send_message(MSPCodes.MSP_RAW_GPS, false, false, function () {
|
||||||
var gpsFixType = i18n.getMessage('gpsFixNone');
|
var gpsFixType = i18n.getMessage('gpsFixNone');
|
||||||
if (FC.GPS_DATA.fix >= 2)
|
if (FC.GPS_DATA.fix >= 2)
|
||||||
|
@ -142,14 +132,6 @@ TABS.setup.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_fast_data() {
|
function get_fast_data() {
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable balancer
|
|
||||||
*/
|
|
||||||
if (mspQueue.shouldDrop()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSPCodes.MSP_ATTITUDE, false, false, function () {
|
MSP.send_message(MSPCodes.MSP_ATTITUDE, false, false, function () {
|
||||||
roll_e.text(i18n.getMessage('initialSetupAttitude', [FC.SENSOR_DATA.kinematics[0]]));
|
roll_e.text(i18n.getMessage('initialSetupAttitude', [FC.SENSOR_DATA.kinematics[0]]));
|
||||||
pitch_e.text(i18n.getMessage('initialSetupAttitude', [FC.SENSOR_DATA.kinematics[1]]));
|
pitch_e.text(i18n.getMessage('initialSetupAttitude', [FC.SENSOR_DATA.kinematics[1]]));
|
||||||
|
@ -159,8 +141,8 @@ TABS.setup.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mspBalancedInterval.add('setup_data_pull_fast', 40, 1, get_fast_data);
|
interval.add('setup_data_pull_fast', get_fast_data, 50);
|
||||||
mspBalancedInterval.add('setup_data_pull_slow', 250, 1, get_slow_data);
|
interval.add('setup_data_pull_slow', get_slow_data, 250);
|
||||||
|
|
||||||
interval.add('gui_analog_update', function () {
|
interval.add('gui_analog_update', function () {
|
||||||
bat_cells_e.text(i18n.getMessage('initialSetupBatteryDetectedCellsValue', [FC.ANALOG.cell_count]));
|
bat_cells_e.text(i18n.getMessage('initialSetupBatteryDetectedCellsValue', [FC.ANALOG.cell_count]));
|
||||||
|
|
17
tabs/sitl.js
17
tabs/sitl.js
|
@ -78,17 +78,6 @@ TABS.sitl.initialize = (callback) => {
|
||||||
GUI.load(path.join(__dirname, "sitl.html"), function () {
|
GUI.load(path.join(__dirname, "sitl.html"), function () {
|
||||||
i18n.localize();
|
i18n.localize();
|
||||||
|
|
||||||
var os = GUI.operating_system;
|
|
||||||
if (os != 'Windows' && os != 'Linux') {
|
|
||||||
|
|
||||||
$('.content_wrapper').find('*').remove();
|
|
||||||
$('.content_wrapper').append(`<h2>${i18n.getMessage('sitlOSNotSupported')}</h2>`);
|
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var currentSim, currentProfile, profiles;
|
var currentSim, currentProfile, profiles;
|
||||||
var mapping = new Array(28).fill(0);
|
var mapping = new Array(28).fill(0);
|
||||||
var serialProtocolls = Ser2TCP.getProtocolls();
|
var serialProtocolls = Ser2TCP.getProtocolls();
|
||||||
|
@ -253,7 +242,7 @@ TABS.sitl.initialize = (callback) => {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (profiles.find(e => { return e.name == name })) {
|
if (profiles.find(e => { return e.name == name })) {
|
||||||
alert(i18n.getMessage('sitlProfileExists'))
|
GUI.alert(i18n.getMessage('sitlProfileExists'))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var eerpromName = name.replace(/[^a-z0-9]/gi, '_').toLowerCase() + ".bin";
|
var eerpromName = name.replace(/[^a-z0-9]/gi, '_').toLowerCase() + ".bin";
|
||||||
|
@ -284,7 +273,7 @@ TABS.sitl.initialize = (callback) => {
|
||||||
profileDeleteBtn_e.on('click', function () {
|
profileDeleteBtn_e.on('click', function () {
|
||||||
|
|
||||||
if (currentProfile.isStdProfile) {
|
if (currentProfile.isStdProfile) {
|
||||||
alert(i18n.getMessage('sitlStdProfileCantDeleted'));
|
GUI.alert(i18n.getMessage('sitlStdProfileCantDeleted'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +374,7 @@ TABS.sitl.initialize = (callback) => {
|
||||||
|
|
||||||
function saveProfiles() {
|
function saveProfiles() {
|
||||||
if (currentProfile.isStdProfile) {
|
if (currentProfile.isStdProfile) {
|
||||||
alert(i18n.getMessage('sitlStdProfileCantOverwritten'));
|
GUI.alert(i18n.getMessage('sitlStdProfileCantOverwritten'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var profilesToSave = [];
|
var profilesToSave = [];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue