Skip to content

Commit

Permalink
SITL and odds and ends
Browse files Browse the repository at this point in the history
  • Loading branch information
Scavanger committed Dec 15, 2024
1 parent fc74ce9 commit 71d8ca5
Show file tree
Hide file tree
Showing 21 changed files with 306 additions and 118 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ sudo mv inav-configurator.desktop /usr/share/applications/
For local development, the **node.js** build system is used.

1. Install node.js
1. From the project folder run `yarn install` and then `npm install`
1. To build the and start the configurator:
1. From the project folder run `npm install` and then `npm install`
1. To build the and start the configurator:
- Run `npm start`.

To build the App run `npm run make` to build for your platform.
Expand Down Expand Up @@ -114,7 +114,9 @@ To be able to open Inspector, set environment variable `NODE_ENV` to `developmen

```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!)

To debug the main thread (source files in `js/main`), just set a breakpoint in VScode.

## Different map providers

Expand Down
13 changes: 8 additions & 5 deletions forge.config.cjs → forge.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
const path = require('path');
const fs = require('fs');
import path from 'node:path';
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';

module.exports = {
const __dirname = path.dirname(fileURLToPath(import.meta.url));

export default {
packagerConfig: {
executableName: "inav-configurator",
asar: false,
Expand Down Expand Up @@ -29,7 +32,7 @@ module.exports = {
renderer: [
{
name: 'bt_device_chooser',
config: 'vite.bt-renderer.config.js',
config: 'vite.bt-dc-renderer.config.js',
},
{
name: 'main_window',
Expand Down Expand Up @@ -67,7 +70,7 @@ module.exports = {
appUserModelId: "com.inav.configurator",
icon: path.join(__dirname, "./assets/windows/inav_installer_icon.ico"),
upgradeCode: "13606ff3-b0bc-4dde-8fac-805bc8aed2f8",
ui : {
ui: {
enabled: false,
chooseDirectory: true,
images: {
Expand Down
Binary file modified images/icons/map/cf_icon_position.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions js/main/child_process.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { spawn } from 'node:child_process'

const child_process = {
_processes: [],
_id: 0,

start: function (command, args, opts, window) {
var process;
try {
process = spawn(command, args, opts);
} catch (err) {
console.log(err);
return -1;
}

this._processes[this._id] = process;

process.stdout.on('data', (data) => {
if (!window.isDestroyed()) {
window.webContents.send('onChildProcessStdout', data.toString());
}
});

process.stderr.on('data', (data) => {
if (!window.isDestroyed()) {
window.webContents.send('onChildProcessStderr', data.toString());
}
});

process.on('error', (error) => {
if (!window.isDestroyed()) {
window.webContents.send('onChildProcessError', error);
}
});

return this._id++;
},

stop: function(handle) {
var process = this._processes[handle];
if (process) {
try {
process.kill();
} catch (err) {
console.log(err);
}
this._processes[handle] = null;
}
},

stopAll: function() {
for (const process in this._processes) {
if (process) {
process.kill();
}
}
this._processes = [];
}
};

export default child_process;
50 changes: 48 additions & 2 deletions js/main/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { chmod, rm } from 'node:fs';
import { app, BrowserWindow, ipcMain, Menu, MenuItem, shell, dialog } from 'electron';
import windowStateKeeper from 'electron-window-state';
import Store from "electron-store";
import prompt from 'electron-prompt';
import path from 'path';
import { fileURLToPath } from 'node:url';
import started from 'electron-squirrel-startup';
Expand All @@ -10,6 +12,7 @@ import { writeFile, readFile } from 'node:fs/promises';
import tcp from './tcp';
import udp from './udp';
import serial from './serial';
import child_process from './child_process';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

Expand Down Expand Up @@ -210,6 +213,7 @@ function createWindow() {
app.on('before-quit', async () => {
await tcp.close();
await serial.close();
child_process.stopAll();
});

app.on('window-all-closed', async () => {
Expand Down Expand Up @@ -273,11 +277,21 @@ app.whenReady().then(() => {
}),

ipcMain.on('dialog.alert', (event, message) => {
event.returnValue = dialog.showMessageBoxSync({ message: message, icon: path.join(__dirname, './../../images/inav_icon_128.png')});
event.returnValue = dialog.showMessageBoxSync({ message: message, icon: path.join(__dirname, 'inav_icon_128.png')});
});

ipcMain.on('dialog.confirm', (event, message) => {
event.returnValue = (dialog.showMessageBoxSync({ message: message, icon: path.join(__dirname, './../../images/inav_icon_128.png'), buttons: ["Yes", "No"]}) == 0);
event.returnValue = (dialog.showMessageBoxSync({ message: message, icon: path.join(__dirname, 'inav_icon_128.png'), buttons: ["Yes", "No"]}) == 0);
});

ipcMain.handle('dialog.prompt', (_event, title, message) => {
return prompt({
title: title,
label: message,
width: 450,
height: 200,
icon: path.join(__dirname, 'inav_icon_128.png'),
}, mainWindow);
});

ipcMain.handle('tcpConnect', (_event, host, port) => {
Expand Down Expand Up @@ -339,6 +353,38 @@ app.whenReady().then(() => {
});
});

ipcMain.handle('chmod', (_event, path, mode) => {
return new Promise(resolve => {
chmod(path, mode, error => {
if (error) {
resolve(error.message)
} else {
resolve(false)
}
});
});
});

ipcMain.handle('rm', (_event, path) => {
return new Promise(resolve => {
rm(path, error => {
if (error) {
resolve(error.message)
} else {
resolve(false)
}
});
});
});

ipcMain.on('startChildProcess', (event, command, args, opts) => {
event.returnValue = child_process.start(path.join(__dirname, 'sitl', command), args, opts, mainWindow);
});

ipcMain.on('killChildProcess', (_event, handle) => {
child_process.stop(handle);
});

// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
Expand Down
10 changes: 9 additions & 1 deletion js/main/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
showSaveDialog: (options) => ipcRenderer.invoke('dialog.showSaveDialog', options),
alertDialog: (message) => ipcRenderer.sendSync('dialog.alert', message),
confirmDialog: (message) => ipcRenderer.sendSync('dialog.confirm', message),
prompt: (title, message) => ipcRenderer.invoke('dialog.prompt', title, message),
tcpConnect: (host, port) => ipcRenderer.invoke('tcpConnect', host, port),
tcpClose: () => ipcRenderer.send('tcpClose'),
tcpSend: (data) => ipcRenderer.invoke('tcpSend', data),
Expand All @@ -30,5 +31,12 @@ contextBridge.exposeInMainWorld('electronAPI', {
onUdpError: (callback) => ipcRenderer.on('udpError', (_event, error) => callback(error)),
onUdpMessage: (callback) => ipcRenderer.on('udpMessage', (_event, data) => callback(data)),
writeFile: (filename, data) => ipcRenderer.invoke('writeFile', filename, data),
readFile: (filename, encoding = 'utf8') => ipcRenderer.invoke('readFile', filename, encoding)
readFile: (filename, encoding = 'utf8') => ipcRenderer.invoke('readFile', filename, encoding),
rm: (path) => ipcRenderer.invoke('rm', path),
chmod: (path, mode) => ipcRenderer.invoke('chmod', path, mode),
startChildProcess: (command, args, opts) => ipcRenderer.sendSync('startChildProcess', command, args, opts),
killChildProcess: (handle) => ipcRenderer.send('killChildProcess', handle),
onChildProcessStdout: (callback) => ipcRenderer.on('onChildProcessStdout', (_event, data) => callback(data)),
onChildProcessStderr: (callback) => ipcRenderer.on('onChildProcessStderr', (_event, data) => callback(data)),
onChildProcessError: (callback) => ipcRenderer.on('onChildProcessError', (_event, error) => callback(error)),
});
41 changes: 25 additions & 16 deletions js/sitl.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict'
//import { chmod, rm } from 'fs';
import { error } from 'jquery';
import { GUI } from './gui';

const serialRXProtocolls = [
Expand Down Expand Up @@ -95,12 +95,12 @@ var SITLProcess = {

spawn : null,
isRunning: false,
process: null,
processHandle: null,

deleteEepromFile(filename) {
rm(`${window.electronAPI.getPath('userData')}/${filename}`, error => {
window.electronAPI.rm(`${window.electronAPI.appGetPath('userData')}/${filename}`).then(error => {
if (error) {
GUI.log(`Unable to reset Demo mode: ${error.message}`);
GUI.log(`Unable to reset Demo mode: ${error}`);
}
});
},
Expand All @@ -111,21 +111,21 @@ var SITLProcess = {
this.stop();

var sitlExePath, eepromPath;
var path = window.electronAPI.getPath('userData');
var path = window.electronAPI.appGetPath('userData');
if (GUI.operating_system == 'Windows') {
sitlExePath = path.join(__dirname, './../resources/sitl/windows/inav_SITL.exe');
sitlExePath = '/windows/inav_SITL.exe';
eepromPath = `${path}\\${eepromFileName}`
} else if (GUI.operating_system == 'Linux') {
sitlExePath = path.join(__dirname, './../resources/sitl/linux/inav_SITL');
sitlExePath = '/linux/inav_SITL';
eepromPath = `${path}/${eepromFileName}`
chmod(sitlExePath, 0o755, err => {
window.electronAPI.chmod(sitlExePath, 0o755).then(err => {
if (err)
console.log(err);
});
} else if (GUI.operating_system == 'MacOS') {
sitlExePath = path.join(__dirname, './../resources/sitl/macos/inav_SITL');
sitlExePath = 'macos/inav_SITL';
eepromPath = `${path}/${eepromFileName}`
chmod(sitlExePath, 0o755, err => {
window.electronAPI.chmod(sitlExePath, 0o755).then(err => {
if (err)
console.log(err);
});
Expand Down Expand Up @@ -176,7 +176,9 @@ var SITLProcess = {
}
}

callback( sitlExePath + " " + args.join(" ") + "\n");
if (callback) {
callback( sitlExePath + " " + args.join(" ") + "\n");
}
this.spawn(sitlExePath, args, callback);
},

Expand All @@ -186,20 +188,26 @@ var SITLProcess = {
if (GUI.operating_system == 'Linux')
opts = { useShell: true };

this.process = window.electronAPI.spawn(path, args, opts);
this.processHandle = window.electronAPI.startChildProcess(path, args, opts);

if (this.processHandle == -1) {
this.isRunning = false;
return;
}

this.isRunning = true;

this.process.stdout.on('data', (data) => {
window.electronAPI.onChildProcessStdout(data => {
if (callback)
callback(data);
});

this.process.stderr.on('data', (data) => {
window.electronAPI.onChildProcessStderr(data => {
if (callback)
callback(data);
});

this.process.on('error', (error) => {
window.electronAPI.onChildProcessError(error => {
if (callback)
callback(error);
this.isRunning = false;
Expand All @@ -209,7 +217,8 @@ var SITLProcess = {
stop: function() {
if (this.isRunning) {
this.isRunning = false;
this.process.kill();
window.electronAPI.killChildProcess(this.processHandle);
this.processHandle = null;
}
}
};
Expand Down
Loading

0 comments on commit 71d8ca5

Please sign in to comment.