Fixes, Readme, Makers

pull/1961/head
Scavanger 5 months ago
parent 6fe68a6b73
commit 0d1502e03d

@ -25,25 +25,25 @@ Depending on the target operating system, _INAV Configurator_ is distributed as
### Windows ### Windows
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases) 1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
1. Download Configurator for Windows platform (win32 or win64 is present) 2. Download Configurator for Windows platform (win32 or win64 is present)
1. Extract ZIP archive 3. Install
1. Run the INAV Configurator app from the unpacked folder * Extract ZIP archive and run the INAV Configurator app from the unpacked folder
1. Configurator is not signed, so you have to allow Windows to run untrusted applications. There might be a monit for it during the first run * OR just use the setup program `INAV Configurator.msi`
### Linux 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
### Outdated, TODO: Update for Electron ### 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 (linux32 and linux64 are 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_linux64-x.y.z-x86_64.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_linux64_x.y.z.deb` or open it with a package manager (e.g. via the File Manager)
* **.tar.gz** 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 **tar.gz** 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 **tar.gz** archive 5. Extract **zip** archive
``` ```
tar -C /tmp/ -xf INAV-Configurator_linuxNN_x.y.z.tar.gz unzip INAV-Configurator_linuxNN_x.y.z.tar.gz -d /tmp/
``` ```
**NN** is the bits of your OS. **x.y.z** is the INAV Configurator version number. **NN** is the bits of your OS. **x.y.z** is the INAV Configurator version number.
@ -72,9 +72,10 @@ sudo mv inav-configurator.desktop /usr/share/applications/
### Mac ### Mac
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases) 1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
1. Download Configurator for the Mac platform 2. Download Configurator for the Mac platform
1. Extract ZIP archive 3. Install
1. Run INAV Configurator * Extract ZIP archive and run INAV Configurator
* OR use the DMG package for installation
## Building and running INAV Configurator locally (for development) ## Building and running INAV Configurator locally (for development)
@ -92,6 +93,13 @@ 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
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```
To build deb and rpm packages for Linux, you have to install the following packages:
- Ubuntu/Debian: `dpkg, fakeroot, rpmbuild, build-essential, libudev-dev`
- 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" ```
@ -99,7 +107,7 @@ Example (note the double -- ):
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 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!)

@ -2,7 +2,7 @@
Name=INAV Configurator Name=INAV Configurator
Comment=Crossplatform configuration tool for the INAV flight control system Comment=Crossplatform configuration tool for the INAV flight control system
Exec=/opt/inav/inav-configurator/inav-configurator Exec=/opt/inav/inav-configurator/inav-configurator
Icon=/opt/inav/inav-configurator/icon/inav_icon_128.png Icon=/opt/inav/inav-configurator/resources/app/assets/linux/icon/inav_icon_128.png
Terminal=false Terminal=false
Type=Application Type=Application
Categories=Utility Categories=Utility

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

@ -1,169 +0,0 @@
; ------------------------------------------
; Installer for INAV
; ------------------------------------------
; It receives from the command line with /D the parameters:
; version
; archName
; archAllowed
; archInstallIn64bit
; sourceFolder
; targetFolder
#define ApplicationName "INAV Configurator"
#define CompanyName "The INAV open source project"
#define CompanyUrl "https://github.com/iNavFlight/inav"
#define ExecutableFileName "inav-configurator.exe"
#define GroupName "INAV"
#define InstallerFileName "INAV-Configurator_" + archName + "_" + version
#define SourcePath "..\..\" + sourceFolder + "\inav-configurator\" + archName
#define TargetFolderName "INAV-Configurator"
#define UpdatesUrl "https://github.com/iNavFlight/inav-configurator/releases"
[CustomMessages]
AppName=inav-configurator
LaunchProgram=Start {#ApplicationName}
[Files]
Source: "{#SourcePath}\*"; DestDir: "{app}"; Flags: recursesubdirs
[Icons]
; Programs group
Name: "{group}\{#ApplicationName}"; Filename: "{app}\{#ExecutableFileName}";
; Desktop icon
Name: "{autodesktop}\{#ApplicationName}"; Filename: "{app}\{#ExecutableFileName}";
; Non admin users, uninstall icon
Name: "{group}\Uninstall {#ApplicationName}"; Filename: "{uninstallexe}"; Check: not IsAdminInstallMode
[Languages]
; English default, it must be first
Name: "en"; MessagesFile: "compiler:Default.isl"
; Official languages
;Name: "ca"; MessagesFile: "compiler:Languages\Catalan.isl"
;Name: "da"; MessagesFile: "compiler:Languages\Danish.isl"
;Name: "de"; MessagesFile: "compiler:Languages\German.isl"
;Name: "es"; MessagesFile: "compiler:Languages\Spanish.isl"
;Name: "fr"; MessagesFile: "compiler:Languages\French.isl"
;Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
;Name: "ja"; MessagesFile: "compiler:Languages\Japanese.isl"
;Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
;Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl"
;Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
;Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl"
; Not official. Sometimes not updated to latest version (strings missing)
;Name: "ga"; MessagesFile: "unofficial_inno_languages\Galician.isl"
;Name: "eu"; MessagesFile: "unofficial_inno_languages\Basque.isl"
;Name: "hr"; MessagesFile: "unofficial_inno_languages\Croatian.isl"
;Name: "hu"; MessagesFile: "unofficial_inno_languages\Hungarian.isl"
;Name: "id"; MessagesFile: "unofficial_inno_languages\Indonesian.isl"
;Name: "ko"; MessagesFile: "unofficial_inno_languages\Korean.isl"
;Name: "lv"; MessagesFile: "unofficial_inno_languages\Latvian.isl"
;Name: "sv"; MessagesFile: "unofficial_inno_languages\Swedish.isl"
;Name: "zh_CN"; MessagesFile: "unofficial_inno_languages\ChineseSimplified.isl"
;Name: "zh_TW"; MessagesFile: "unofficial_inno_languages\ChineseTraditional.isl"
; Not available
; pt_BR (Portuguese Brasileiro)
[Run]
; Add a checkbox to start the app after installed
Filename: {app}\{cm:AppName}.exe; Description: {cm:LaunchProgram,{cm:AppName}}; Flags: nowait postinstall skipifsilent
[Setup]
AppId=2e5662ca-1fb3-8f1e-a7e1-e390add7a19d
AppName={#ApplicationName}
AppPublisher={#CompanyName}
AppPublisherURL={#CompanyUrl}
AppUpdatesURL={#UpdatesUrl}
AppVersion={#version}
ArchitecturesAllowed={#archAllowed}
ArchitecturesInstallIn64BitMode={#archInstallIn64bit}
Compression=lzma2
DefaultDirName={autopf}\{#GroupName}\{#TargetFolderName}
DefaultGroupName={#GroupName}\{#ApplicationName}
LicenseFile=..\..\LICENSE
MinVersion=6.2
OutputBaseFilename={#InstallerFileName}
OutputDir=..\..\{#targetFolder}\
PrivilegesRequiredOverridesAllowed=commandline dialog
SetupIconFile=inav_installer_icon.ico
ShowLanguageDialog=yes
SolidCompression=yes
UninstallDisplayIcon={app}\{#ExecutableFileName}
UninstallDisplayName={#ApplicationName}
WizardImageFile=inav_installer.bmp
WizardSmallImageFile=inav_installer_small.bmp
WizardStyle=modern
[Code]
function GetOldNsisUninstallerPath(): String;
var
RegKey: String;
begin
Result := '';
// Look into the different registry entries: win32, win64 and without user rights
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\INAV Configurator', 'UninstallString', Result) then
begin
if not RegQueryStringValue(HKLM, 'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\INAV Configurator', 'UninstallString', Result) then
begin
RegQueryStringValue(HKCU, 'SOFTWARE\INAV\INAV Configurator', 'UninstallString', Result)
end;
end;
end;
function GetQuietUninstallerPath(): String;
var
RegKey: String;
begin
Result := '';
RegKey := Format('%s\%s_is1', ['Software\Microsoft\Windows\CurrentVersion\Uninstall', '{#emit SetupSetting("AppId")}']);
if not RegQueryStringValue(HKEY_LOCAL_MACHINE, RegKey, 'QuietUninstallString', Result) then
begin
RegQueryStringValue(HKEY_CURRENT_USER, RegKey, 'QuietUninstallString', Result);
end;
end;
function InitializeSetup(): Boolean;
var
ResultCode: Integer;
ParameterStr : String;
UninstPath : String;
begin
Result := True;
// Check if the application is already installed by the old NSIS installer, and uninstall it
UninstPath := GetOldNsisUninstallerPath();
// Found, start uninstall
if UninstPath <> '' then
begin
UninstPath := RemoveQuotes(UninstPath);
// Add this parameter to not return until uninstall finished. The drawback is that the uninstaller file is not deleted
ParameterStr := '_?=' + ExtractFilePath(UninstPath);
if Exec(UninstPath, ParameterStr, '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
begin
// Delete the unistaller file and empty folders. Not deleting the files.
DeleteFile(UninstPath);
DelTree(ExtractFilePath(UninstPath), True, False, True);
end
else begin
Result := False;
MsgBox('Error uninstalling old Configurator ' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK);
end;
end
else begin
// Search for new Inno Setup installations
UninstPath := GetQuietUninstallerPath();
if UninstPath <> '' then
begin
if not Exec('>', UninstPath, '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
begin
Result := False;
MsgBox('Error uninstalling Configurator ' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK);
end;
end;
end;
end;

@ -0,0 +1,162 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<!-- http://wixtoolset.org/documentation/manual/v3/xsd/wix/product.html -->
<Product Id="{{ProductCode}}"
UpgradeCode="{{UpgradeCode}}"
Name = "{{ApplicationName}}"
Version="{{Version}}"
Manufacturer="{{Manufacturer}}"
Language="{{Language}}">
<!-- Only run this installer on Windows 7 or up (or if it"s already installed, I guess) -->
<!-- <Condition Message="This application is only supported on Windows 7 or higher.">
<![CDATA[Installed OR (VersionNT >= 601)]]>
</Condition> -->
<!-- http://wixtoolset.org/documentation/manual/v3/xsd/wix/package.html -->
<Package InstallerVersion="405"
Compressed="yes"
Comments="Windows Installer Package"
Platform="{{Platform}}"
InstallScope="{{PackageScope}}"/>
<!-- Don't allow downgrades -->
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A later version of this product is already installed. Setup will now exit."/>
<!-- This will hide our Uninstall entry in Apps & Features. We doing this so
we can write our own which we can better control. -->
<Property Id="ARPSYSTEMCOMPONENT" Value="1" />
<!-- While the MSI package is hidden in Apps & Features, it can still be queried
via PowerShell and other means. To differentiate we give the public entry a slightly
different name to make admins life easier. -->
<Property Id="VisibleProductName" Value="{{ApplicationName}}" />
<!-- Tells the package to install perUser or perMachine. In case of perUser, all
files will be redirected to the user profile and all registry entries to HKCU. -->
<Property Id="MSIINSTALLPERUSER" Secure="yes" Value="{{InstallPerUser}}" />
<!-- Overides the default install mode. It solves a problem where
individual packaged files that have the same version as in previous
installed App version will be deleted if the files are in use during
this upgrade. Unfortunately this causes an ICE 40 warning during linking. -->
<Property Id="REINSTALLMODE" Value="emus" />
<!-- Overrides the default reboot behavior if files are in use during the upgrade.
By default, this will be set to "ReallySuppress" to make sure no unexpected reboot will happpen.-->
<Property Id="REBOOT" Value="{{RebootMode}}" />
<!-- Installlation level to use that determines which features are installed.
see guides/enduser.md to check which Install Level maps to which feature that will
correspondingly get installed.
If not set, this will default to "2" (Main Feature, Launch On Login) -->
<Property Id="INSTALLLEVEL" Value="{{InstallLevel}}" />
<!-- Allows to customize the Windows user group that gets access rights on
the install folder in cas the auto-updater is installed. User that run the App
must be part of that user group to be able to auto-update. -->
<Property Id="UPDATERUSERGROUP" Value="Users" />
<!-- A property to define whether the auto-updater is enabled when the
feature gets installed. This way the update can be installed but also be disabled
by overwriting the default value. -->
<Property Id="AUTOUPDATEENABLED" Value="1" />
<!-- Necessary registry search to find the install path which is used by the
PurgeOnUninstall action. Since this package can be installed perUser or perMachine,
we have to look in both places. First successful search wins. -->
<Property Id="INSTALLPATH">
<RegistrySearch Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{{ProductCode}}}.msq"
Root="HKCU"
Type="raw"
Id="INSTALLPATH_REGSEARCH_HKCU"
Name="InstallPath"
Win64="{{Win64YesNo}}"/>
<RegistrySearch Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{{ProductCode}}}.msq"
Root="HKLM"
Type="raw"
Id="INSTALLPATH_REGSEARCH_HKLM"
Name="InstallPath"
Win64="{{Win64YesNo}}"/>
</Property>
<!-- Lets change the product name depending on the perUser installMode.
This way the user and admins can see in which scope the MSI was installed. -->
<SetProperty Action="SetVisibleProductName" Id="VisibleProductName" Sequence="both" Before="AppSearch" Value="{{ApplicationName}} (User)">
<![CDATA[MSIINSTALLPERUSER = "1"]]>
</SetProperty>
<!-- Again we give thee MSI generaten entry a slightly different name to help
differentiate between the public one and the invisible one. -->
<SetProperty Action="SetProductName" Id="ProductName" Sequence="both" Before="AppSearch" Value="{{ApplicationName}} (User - MSI)">
<![CDATA[MSIINSTALLPERUSER = "1"]]>
</SetProperty>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<!-- {{Icon}}-->
<!-- {{UI}} -->
<!-- Step 2: Add files and directories -->
<Directory Id="TARGETDIR" Name="SourceDir">
<!-- Installation files to %PROGRAMFILES% -->
<Directory Id="{{ProgramFilesFolder}}">
<!-- {{Directories}} -->
</Directory>
<!-- Desktop -->
<Directory Id="DesktopFolder" Name="Desktop" />
<!-- Start Menu -->
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="{{ShortcutFolderName}}"/>
</Directory>
</Directory>
<!-- Step 3: Add app to Start Menu -->
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="{{ApplicationShortcutGuid}}" Win64="{{Win64YesNo}}">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="{{ShortcutName}}"
Description="{{ApplicationDescription}}"
Target="[APPLICATIONROOTDIRECTORY]{{ApplicationBinary}}.exe"
WorkingDirectory="APPLICATIONROOTDIRECTORY">
<!-- {{ShortcutProperties}} -->
</Shortcut>
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU"
Key="Software\Microsoft\{{ApplicationShortName}}"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
</DirectoryRef>
<!-- Step 4: Add app desktop shortcut -->
<DirectoryRef Id="DesktopFolder">
<Component Id="DesktopShortcut" Guid="{{DesktopShortcutGuid}}" >
<Shortcut Id="MyDesktopShortcut"
Name="{{ShortcutName}}"
Description="{{ApplicationDescription}}"
Target="[APPLICATIONROOTDIRECTORY]{{ApplicationBinary}}.exe"
WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
<RegistryValue Root="HKCU"
Key="Software\Microsoft\{{ApplicationShortName}}"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes" />
</Component>
</DirectoryRef>
<!-- {{AutoUpdatePermissions}} -->
<!-- Lets cleanup any files that are were not part of the initial install
via this MSI. Such as newer versions installed by the auto-updater. -->
<DirectoryRef Id="APPLICATIONROOTDIRECTORY">
<Component Id="PurgeOnUninstall" Guid="{{RandomGuid}}" Win64="{{Win64YesNo}}">
<CreateFolder/>
<util:RemoveFolderEx On="uninstall" Property="INSTALLPATH" />
</Component>
</DirectoryRef>
<Feature Id="Complete" Title="{{ApplicationName}} ({{SemanticVersion}})" Description="The complete package." Display="expand" Level="1" {{ConfigurableDirectory}}>
<!-- Step 5: Tell WiX to install the files -->
<Feature Id="MainApplication" Title="Main Application" Level="1" Description="The main components to run the applications." >
<!-- {{ComponentRefs}} -->
<ComponentRef Id="ApplicationShortcut" />
<ComponentRef Id="DesktopShortcut" />
<ComponentRef Id="PurgeOnUninstall" />
</Feature>
<!-- {{AutoLaunchFeature}} -->
<!-- {{AutoUpdateFeature}} -->
</Feature>
<!-- {{AutoRun}} -->
</Product>
</Wix>

@ -1,27 +1,81 @@
const path = require('path');
const fs = require('fs');
module.exports = { module.exports = {
packagerConfig: { packagerConfig: {
executableName: "inav-configurator",
asar: false, asar: false,
icon: 'images/inav' icon: 'images/inav',
ignore: [
"^(\/\.vscode$)",
"^(\/support$)",
".gitattributes",
".gitignore",
"3D_model_creation.md",
"LICENSE",
"MAPPROXY.md",
"package-lock.json",
"README.md",
"inav_icon_128.psd",
]
}, },
rebuildConfig: {}, rebuildConfig: {},
makers: [ makers: [
{ {
name: '@electron-forge/maker-squirrel', name: '@electron-forge/maker-wix',
config: { config: {
iconUrl: "https://raw.githubusercontent.com/iNavFlight/inav-configurator/master/images/inav.ico", name: "INAV Configurator",
loadingGif: "images/inav-installing.gif" shortName: "INAV",
}, description: "Configurator for the open source flight controller software INAV.",
programFilesFolderName: "inav-configurator",
shortcutFolderName: "INAV",
manufacturer: "The INAV open source project",
appUserModelId: "com.inav.configurator",
icon: path.join(__dirname, "./assets/windows/inav_installer_icon.ico"),
upgradeCode: "13606ff3-b0bc-4dde-8fac-805bc8aed2f8",
ui : {
enabled: false,
chooseDirectory: true,
images: {
background: path.join(__dirname, "./assets/windows/background.jpg"),
banner: path.join(__dirname, "./assets/windows/banner.jpg")
}
},
beforeCreate: (msiCreator) => {
return new Promise((resolve, reject) => {
fs.readFile(path.join(__dirname,"./assets/windows/wix.xml"), "utf8" , (err, content) => {
if (err) {
reject (err);
}
msiCreator.wixTemplate = content;
resolve();
});
});
}
}
},
{
name: '@electron-forge/maker-dmg',
config: {
name: "INAV Configurator",
background: "./assets/osx/dmg-background.png"
}
}, },
{ {
name: '@electron-forge/maker-zip', name: '@electron-forge/maker-zip',
platforms: ['win32', 'darwin'], platforms: ['win32', 'linux', 'darwin'],
}, },
{ {
name: '@electron-forge/maker-deb', name: '@electron-forge/maker-deb',
config: { config: {
options: { options: {
icon: "images/inav_icon_128.png" name: "inav-configurator",
productName: "INAV Configurator",
categories: ["Utility"],
icon: "./assets/linux/icon/inav_icon_128.png",
description: "Configurator for the open source flight controller software INAV.",
homepage: "https://github.com/inavflight/",
} }
}, },
}, },
@ -29,7 +83,13 @@ module.exports = {
name: '@electron-forge/maker-rpm', name: '@electron-forge/maker-rpm',
config: { config: {
options: { options: {
icon: "images/inav_icon_128.png" name: "inav-configurator",
productName: "INAV Configurator",
license: "GPL-3.0",
categories: ["Utility"],
icon: "./assets/linux/icon/inav_icon_128.png",
description: "Configurator for the open source flight controller software INAV.",
homepage: "https://github.com/inavflight/",
} }
}, },
}, },

@ -3,7 +3,7 @@
const semver = require('semver'); const semver = require('semver');
const { GUI } = require('./gui'); const { GUI } = require('./gui');
const jBox = require('./libraries/jBox/jBox.min.js'); const jBox = require('./libraries/jBox/jBox.min');
const i18n = require('./localization'); const i18n = require('./localization');
var appUpdater = appUpdater || {}; var appUpdater = appUpdater || {};

@ -1,12 +1,12 @@
window.$ = window.jQuery = require('jquery'), window.$ = window.jQuery = require('jquery'),
require('jquery-ui-dist/jquery-ui'), require('jquery-ui-dist/jquery-ui'),
require('jquery-textcomplete'), require('jquery-textcomplete'),
require('./libraries/jquery.flightindicators.js'), require('./libraries/jquery.flightindicators'),
require('./libraries/jquery.nouislider.all.min.js'), require('./libraries/jquery.nouislider.all.min'),
require('./libraries/jquery.ba-throttle-debounce.js'); require('./libraries/jquery.ba-throttle-debounce');
const { app } = require('@electron/remote'); const { app } = require('@electron/remote');
const d3 = require('./libraries/d3.min.js'); const d3 = require('./libraries/d3.min');
const Store = require('electron-store'); const Store = require('electron-store');
const store = new Store(); const store = new Store();
@ -14,15 +14,15 @@ const { GUI, TABS } = require('./gui');
const CONFIGURATOR = require('./data_storage'); const CONFIGURATOR = require('./data_storage');
const FC = require('./fc'); const FC = require('./fc');
const { globalSettings, UnitType } = require('./globalSettings'); const { globalSettings, UnitType } = require('./globalSettings');
const { PLATFORM } = require('./model.js') const { PLATFORM } = require('./model')
const i18n = require('./localization'); const i18n = require('./localization');
const SerialBackend = require('./serial_backend'); const SerialBackend = require('./serial_backend');
const MSP = require('./msp'); const MSP = require('./msp');
const MSPCodes = require('./../js/msp/MSPCodes'); const MSPCodes = require('./../js/msp/MSPCodes');
const mspHelper = require('./msp/MSPHelper.js'); const mspHelper = require('./msp/MSPHelper');
const update = require('./globalUpdates.js'); const update = require('./globalUpdates');
const appUpdater = require('./appUpdater.js'); const appUpdater = require('./appUpdater');
const CliAutoComplete = require('./CliAutoComplete.js'); const CliAutoComplete = require('./CliAutoComplete');
const { SITLProcess } = require('./sitl'); const { SITLProcess } = require('./sitl');
; ;
process.on('uncaughtException', function (error) { process.on('uncaughtException', function (error) {
@ -229,19 +229,19 @@ $(function() {
TABS.modes.initialize(content_ready); TABS.modes.initialize(content_ready);
break; break;
case 'gps': case 'gps':
require('./../tabs/gps.js'); require('./../tabs/gps');
TABS.gps.initialize(content_ready); TABS.gps.initialize(content_ready);
break; break;
case 'magnetometer': case 'magnetometer':
require('./../tabs/magnetometer.js'); require('./../tabs/magnetometer');
TABS.magnetometer.initialize(content_ready); TABS.magnetometer.initialize(content_ready);
break; break;
case 'mission_control': case 'mission_control':
require('./../tabs/mission_control.js'); require('./../tabs/mission_control');
TABS.mission_control.initialize(content_ready); TABS.mission_control.initialize(content_ready);
break; break;
case 'mixer': case 'mixer':
require('./../tabs/mixer.js'); require('./../tabs/mixer');
TABS.mixer.initialize(content_ready); TABS.mixer.initialize(content_ready);
break; break;
case 'outputs': case 'outputs':

@ -1,16 +1,16 @@
'use strict'; 'use strict';
const { GUI } = require('./../js/gui'); const { GUI } = require('./../js/gui');
const FC = require('./fc.js'); const FC = require('./fc');
const MSP = require('./msp'); const MSP = require('./msp');
const MSPCodes = require('./../js/msp/MSPCodes'); const MSPCodes = require('./../js/msp/MSPCodes');
const mspHelper = require('./msp/MSPHelper'); const mspHelper = require('./msp/MSPHelper');
const MSPChainerClass = require('./msp/MSPchainer.js'); const MSPChainerClass = require('./msp/MSPchainer');
const features = require('./feature_framework'); const features = require('./feature_framework');
const periodicStatusUpdater = require('./periodicStatusUpdater.js'); const periodicStatusUpdater = require('./periodicStatusUpdater');
const { mixer } = require('./model'); const { mixer } = require('./model');
const jBox = require('./libraries/jBox/jBox.min.js'); const jBox = require('./libraries/jBox/jBox.min');
const i18n = require('./localization.js'); const i18n = require('./localization');
var savingDefaultsModal; var savingDefaultsModal;

@ -10,8 +10,8 @@ const ProgrammingPidStatus = require('./programmingPidStatus');
const WaypointCollection = require('./waypointCollection'); const WaypointCollection = require('./waypointCollection');
const OutputMappingCollection = require('./outputMapping'); const OutputMappingCollection = require('./outputMapping');
const SafehomeCollection = require('./safehomeCollection'); const SafehomeCollection = require('./safehomeCollection');
const FwApproachCollection = require('./fwApproachCollection.js') const FwApproachCollection = require('./fwApproachCollection')
const { PLATFORM } = require('./model.js') const { PLATFORM } = require('./model')
const VTX = require('./vtx'); const VTX = require('./vtx');
const BitHelper = require('./bitHelper'); const BitHelper = require('./bitHelper');
@ -94,7 +94,7 @@ var FC = {
return (this.MIXER_CONFIG.platformType == PLATFORM.AIRPLANE); return (this.MIXER_CONFIG.platformType == PLATFORM.AIRPLANE);
}, },
isMultirotor: function () { isMultirotor: function () {
return (this.MIXER_CONFIG.platformType == PLATFORM.MULTIROTOR || MIXER_CONFIG.platformType == PLATFORM.TRICOPTER); return (this.MIXER_CONFIG.platformType == PLATFORM.MULTIROTOR || this.MIXER_CONFIG.platformType == PLATFORM.TRICOPTER);
}, },
isRpyFfComponentUsed: function () { isRpyFfComponentUsed: function () {
return true; // Currently all planes have roll, pitch and yaw FF return true; // Currently all planes have roll, pitch and yaw FF

@ -1,5 +1,6 @@
'use strict'; 'use strict';
const path = require('path');
const ol = require('openlayers'); const ol = require('openlayers');
const { GUI } = require('./gui'); const { GUI } = require('./gui');
@ -139,7 +140,7 @@ const groundstation = (function () {
anchor: [0.5, 0.5], anchor: [0.5, 0.5],
opacity: 1, opacity: 1,
scale: 0.6, scale: 0.6,
src: '../images/icons/icon_mission_airplane.png' src: path.join(__dirname, './../images/icons/icon_mission_airplane.png')
})) }))
}); });
privateScope.cursorPosition = new ol.geom.Point(ol.proj.fromLonLat([lon, lat])); privateScope.cursorPosition = new ol.geom.Point(ol.proj.fromLonLat([lon, lat]));

@ -21,12 +21,12 @@ const timeout = require('./timeouts');
const mspBalancedInterval = require('./msp_balanced_interval'); 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.js'); const update = require('./globalUpdates');
const BitHelper = require('./bitHelper.js'); const BitHelper = require('./bitHelper');
const BOARD = require('./boards.js'); const BOARD = require('./boards');
const jBox = require('./libraries/jBox/jBox.min.js'); const jBox = require('./libraries/jBox/jBox.min');
const groundstation = require('./groundstation.js'); const groundstation = require('./groundstation');
const ltmDecoder = require('./ltmDecoder.js'); const ltmDecoder = require('./ltmDecoder');
var SerialBackend = (function () { var SerialBackend = (function () {

@ -211,7 +211,7 @@ var SITLProcess = {
sitlExePath = path.join(__dirname, './../resources/sitl/windows/inav_SITL.exe'); sitlExePath = path.join(__dirname, './../resources/sitl/windows/inav_SITL.exe');
eepromPath = `${app.getPath('userData')}\\${eepromFileName}` eepromPath = `${app.getPath('userData')}\\${eepromFileName}`
} else if (GUI.operating_system == 'Linux') { } else if (GUI.operating_system == 'Linux') {
sitlExePath = './../resources/sitl/linux/inav_SITL'; sitlExePath = path.join(__dirname, './../resources/sitl/linux/inav_SITL');
eepromPath = `${app.getPath('userData')}/${eepromFileName}` eepromPath = `${app.getPath('userData')}/${eepromFileName}`
chmod(sitlExePath, 0o755, err => { chmod(sitlExePath, 0o755, err => {
if (err) if (err)

@ -421,7 +421,7 @@ let WaypointCollection = function () {
self.getElevation = async function(globalSettings) { self.getElevation = async function(globalSettings) {
const [nLoop, point2measure, altPoint2measure, namePoint2measure, refPoint2measure] = self.getPoint2Measure(true); const [nLoop, point2measure, altPoint2measure, namePoint2measure, refPoint2measure] = self.getPoint2Measure(true);
let lengthMission = self.getDistance(true); let lengthMission = self.getDistance(true);
let totalMissionDistance = lengthMission[lengthMission.length -1].toFixed(1); let totalMissionDistance = lengthMission.length >= 1 ? lengthMission[lengthMission.length -1].toFixed(1) : 0;
let samples; let samples;
let sampleMaxNum; let sampleMaxNum;
let sampleDistance; let sampleDistance;

887
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -45,8 +45,9 @@
"@electron-forge/cli": "^7.2.0", "@electron-forge/cli": "^7.2.0",
"@electron-forge/maker-deb": "^7.2.0", "@electron-forge/maker-deb": "^7.2.0",
"@electron-forge/maker-rpm": "^7.2.0", "@electron-forge/maker-rpm": "^7.2.0",
"@electron-forge/maker-squirrel": "^7.2.0",
"@electron-forge/maker-zip": "^7.2.0", "@electron-forge/maker-zip": "^7.2.0",
"@electron-forge/maker-dmg": "^7.2.0",
"@electron-forge/maker-wix": "^7.2.0",
"electron": "28.1.4" "electron": "28.1.4"
} }
} }

@ -249,7 +249,7 @@
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.35); box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.35);
width: 90px; width: 90px;
height: 90px; height: 90px;
background-image: url(/images/icons/cf_icon_sdcard.svg); background-image: url(./../../../images/icons/cf_icon_sdcard.svg);
background-position: 21px 20px; background-position: 21px 20px;
background-size: 50px 50px; background-size: 50px 50px;
background-repeat: no-repeat; background-repeat: no-repeat;

@ -9,9 +9,9 @@ const MSP = require('./../js/msp');
const { GUI, TABS } = require('./../js/gui'); const { GUI, TABS } = require('./../js/gui');
const FC = require('./../js/fc'); const FC = require('./../js/fc');
const timeout = require('./../js/timeouts'); const timeout = require('./../js/timeouts');
const interval = require('./../js/intervals.js'); const interval = require('./../js/intervals');
const i18n = require('./../js/localization'); const i18n = require('./../js/localization');
const jBox = require('./../js/libraries/jBox/jBox.min.js'); const jBox = require('./../js/libraries/jBox/jBox.min');
TABS.calibration = {}; TABS.calibration = {};

@ -12,7 +12,7 @@ const i18n = require('./../js/localization');
const { globalSettings } = require('./../js/globalSettings'); 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.js'); const jBox = require('./../js/libraries/jBox/jBox.min');
TABS.cli = { TABS.cli = {
lineDelayMs: 50, lineDelayMs: 50,

@ -8,8 +8,8 @@ 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.js'); const mspBalancedInterval = require('./../js/msp_balanced_interval');
const mspQueue = require('./../js/serial_queue.js'); 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');
@ -17,7 +17,7 @@ const Settings = require('./../js/settings');
const serialPortHelper = require('./../js/serialPortHelper'); const serialPortHelper = require('./../js/serialPortHelper');
const features = require('./../js/feature_framework'); const features = require('./../js/feature_framework');
const { globalSettings } = require('./../js/globalSettings'); const { globalSettings } = require('./../js/globalSettings');
const jBox = require('./../js/libraries/jBox/jBox.min.js'); const jBox = require('./../js/libraries/jBox/jBox.min');
const SerialBackend = require('../js/serial_backend'); const SerialBackend = require('../js/serial_backend');
@ -307,7 +307,7 @@ TABS.gps.initialize = function (callback) {
anchor: [0.5, 1], anchor: [0.5, 1],
opacity: 1, opacity: 1,
scale: 0.5, scale: 0.5,
src: '../../images/icons/cf_icon_position.png' src: path.join(__dirname, './../images/icons/cf_icon_position.png')
})) }))
}); });
@ -366,7 +366,7 @@ TABS.gps.initialize = function (callback) {
rotation: vehicle.headingDegrees * (Math.PI / 180), rotation: vehicle.headingDegrees * (Math.PI / 180),
scale: 0.8, scale: 0.8,
anchor: [0.5, 0.5], anchor: [0.5, 0.5],
src: '../resources/adsb/' + ADSB_VEHICLE_TYPE[vehicle.emitterType], src: path.join(__dirname, './../resources/adsb/' + ADSB_VEHICLE_TYPE[vehicle.emitterType]),
})), })),
text: new ol.style.Text(({ text: new ol.style.Text(({
text: vehicle.callsign, text: vehicle.callsign,

@ -10,8 +10,8 @@ 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.js'); const mspBalancedInterval = require('./../js/msp_balanced_interval');
const mspQueue = require('./../js/serial_queue.js'); 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 CONFIGURATOR = require('./../js/data_storage'); const CONFIGURATOR = require('./../js/data_storage');
@ -24,9 +24,9 @@ const Safehome = require('./../js/safehome');
const SafehomeCollection = require('./../js/safehomeCollection'); const SafehomeCollection = require('./../js/safehomeCollection');
const { ApproachDirection, FwApproach } = require('./../js/fwApproach'); const { ApproachDirection, FwApproach } = require('./../js/fwApproach');
const FwApproachCollection = require('./../js/fwApproachCollection'); const FwApproachCollection = require('./../js/fwApproachCollection');
const SerialBackend = require('./../js/serial_backend.js'); 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.js'); const Plotly = require('./../js/libraries/plotly-latest.min');
var MAX_NEG_FW_LAND_ALT = -2000; // cm var MAX_NEG_FW_LAND_ALT = -2000; // cm
@ -68,7 +68,6 @@ TABS.mission_control.initialize = function (callback) {
var textGeom; var textGeom;
let isOffline = false; let isOffline = false;
let selectedSafehome; let selectedSafehome;
let rthUpdateInterval = 0;
let $safehomeContentBox; let $safehomeContentBox;
let $waypointOptionsTableBody; let $waypointOptionsTableBody;
let settings = {speed: 0, alt: 5000, safeRadiusSH: 50, fwApproachAlt: 60, fwLandAlt: 5, maxDistSH: 0, fwApproachLength: 0, fwLoiterRadius: 0, bingDemModel: false}; let settings = {speed: 0, alt: 5000, safeRadiusSH: 50, fwApproachAlt: 60, fwLandAlt: 5, maxDistSH: 0, fwApproachLength: 0, fwLoiterRadius: 0, bingDemModel: false};
@ -326,18 +325,6 @@ TABS.mission_control.initialize = function (callback) {
'\nAlt: ' + FC.SENSOR_DATA.altitude + '\nAlt: ' + FC.SENSOR_DATA.altitude +
'm\nSpeed: ' + FC.GPS_DATA.speed + 'cm/s\n' + 'm\nSpeed: ' + FC.GPS_DATA.speed + 'cm/s\n' +
'Dist: ' + FC.GPS_DATA.distanceToHome + 'm'); 'Dist: ' + FC.GPS_DATA.distanceToHome + 'm');
//update RTH every 5th GPS update since it really shouldn't change
if(rthUpdateInterval >= 5)
{
FC.MISSION_PLANNER.bufferPoint.number = -1; //needed to get point 0 which id RTH
MSP.send_message(MSPCodes.MSP_WP, mspHelper.crunch(MSPCodes.MSP_WP), false, function rth_update() {
var coord = ol.proj.fromLonLat([FC.MISSION_PLANNER.bufferPoint.lon, FC.MISSION_PLANNER.bufferPoint.lat]);
rthGeo.setCoordinates(coord);
});
rthUpdateInterval = 0;
}
rthUpdateInterval++;
} }
} }
@ -1276,7 +1263,11 @@ TABS.mission_control.initialize = function (callback) {
if (disableMarkerEdit) { if (disableMarkerEdit) {
$('#missionDistance').text('N/A'); $('#missionDistance').text('N/A');
} else { } else {
$('#missionDistance').text(lengthMission[lengthMission.length -1] != -1 ? lengthMission[lengthMission.length -1].toFixed(1) : 'infinite'); if (lengthMission.length >= 1) {
$('#missionDistance').text(lengthMission[lengthMission.length -1].toFixed(1));
} else {
$('#missionDistance').text('infinite');
}
} }
} }

@ -12,7 +12,7 @@ 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 mspBalancedInterval = require('./../js/msp_balanced_interval');
const jBox = require('../js/libraries/jBox/jBox.min.js'); const jBox = require('../js/libraries/jBox/jBox.min');
TABS.mixer = {}; TABS.mixer = {};

@ -17,7 +17,7 @@ const Settings = require('./../js/settings');
const { globalSettings } = require('./../js/globalSettings'); const { globalSettings } = require('./../js/globalSettings');
const { PortHandler } = require('./../js/port_handler'); const { PortHandler } = require('./../js/port_handler');
const i18n = require('./../js/localization'); const i18n = require('./../js/localization');
const jBox = require('./../js/libraries/jBox/jBox.min.js'); const jBox = require('./../js/libraries/jBox/jBox.min');
var SYM = SYM || {}; var SYM = SYM || {};

@ -5,18 +5,18 @@ 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.js'); const mspBalancedInterval = require('./../js/msp_balanced_interval');
const mspQueue = require('./../js/serial_queue.js') 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');
const FC = require('./../js/fc'); const FC = require('./../js/fc');
const i18n = require('./../js/localization'); const i18n = require('./../js/localization');
const BitHelper = require('../js/bitHelper'); const BitHelper = require('../js/bitHelper');
const Settings = require('./../js/settings.js'); const Settings = require('./../js/settings');
const features = require('./../js/feature_framework.js'); const features = require('./../js/feature_framework');
const { mixer, PLATFORM } = require('./../js/model'); const { mixer, PLATFORM } = require('./../js/model');
const timeout = require('./../js/timeouts.js') const timeout = require('./../js/timeouts')
const interval = require('./../js/intervals.js'); const interval = require('./../js/intervals');
TABS.outputs = { TABS.outputs = {
allowTestMode: false, allowTestMode: false,

@ -120,7 +120,7 @@ TABS.sitl.initialize = (callback) => {
var $sitlLog = $('#sitlLog'); var $sitlLog = $('#sitlLog');
$sitlLog.val(SITL_LOG); $sitlLog.val(SITL_LOG);
if ($sitlLog) { if ($sitlLog && $sitlLog.length == 1) {
$sitlLog.val(SITL_LOG); $sitlLog.val(SITL_LOG);
$sitlLog.animate({scrollTop: $sitlLog[0].scrollHeight - $sitlLog.height()}, "fast"); $sitlLog.animate({scrollTop: $sitlLog[0].scrollHeight - $sitlLog.height()}, "fast");
} }
@ -510,7 +510,7 @@ TABS.sitl.initialize = (callback) => {
function appendLog(message){ function appendLog(message){
SITL_LOG += message; SITL_LOG += message;
var $sitlLog = $('#sitlLog'); var $sitlLog = $('#sitlLog');
if ($sitlLog) { if ($sitlLog && $sitlLog.length == 1) {
$sitlLog.val(SITL_LOG); $sitlLog.val(SITL_LOG);
$sitlLog.animate({scrollTop: $sitlLog[0].scrollHeight - $sitlLog.height()}, "fast"); $sitlLog.animate({scrollTop: $sitlLog[0].scrollHeight - $sitlLog.height()}, "fast");
} }

Loading…
Cancel
Save