/**
* This is the main script of the application.
* @module Main
* @author Edouard Denomme <>
* @author Cedric Godin <>
* @author Edouard Legare <>
*/
const { app, BrowserWindow, ipcMain } = require('electron');
const events = require('events');
const rosnodejs = require('rosnodejs');
// eslint-disable-next-line camelcase
const std_msgs = rosnodejs.require('std_msgs').msg;
const path = require('path');
/**
* Keep a global reference of the window object so it doesn't automatically close.
* @type {BrowserWindow}
*/
let win;
/**
* Hub event emitter.
* @type {events.EventEmitter}
*/
const hub = new events.EventEmitter();
/**
* Interface between the msg data in ipc and hub
*/
ipcMain.on('msg', (event, arg) => {
hub.emit('msg', arg);
});
/**
* Create the window, loads the html into it and set events.
* @function createWindow
*
* @fires rosdata
*/
function createWindow() {
/**
* Create the browser window.
*/
win = new BrowserWindow({
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
preload: path.join(__dirname, 'ipcInit.js'),
},
});
/**
* Loads the html into the browser.
*/
win.loadFile('index.html');
/**
* Open the DevTools.
*/
win.webContents.openDevTools();
/**
* Send data from ROS to the server.
* @event rosdata
* @type {object}
* @property {String} data - Data coming from ROS to be sent to the server.
*/
hub.on('rosdata', (data) => {
win.webContents.send('rosdata', data);
});
/**
* Emitted when the window is closed, remove listener and remove the window.
*/
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
hub.removeAllListeners('rosdata');
win = null;
});
}
/**
* Start the electron application
* @function startApp
*/
function startApp() {
/**
* Create the window on event.
*/
app.on('ready', createWindow);
/**
* Quit when all windows are closed.
*/
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
/**
* Create the window when activated
*/
app.on('activate', () => {
if (win === null) {
createWindow();
}
});
}
/**
* Start all the necessary ROS nodes
* @function startNode
*
* @fires data
* @fires patrol-plan
* @fires msg
* @fires parameters_response
*/
function startNode() {
rosnodejs.initNode('/electron_webrtc').then(async (nodeHandle) => {
/** @member {String} */
let webRtcServerUrl;
// let videoDeviceLabel;
try {
webRtcServerUrl = await nodeHandle.getParam('/electron_webrtc/webrtc_server_url');
// var videoDeviceLabel = await nodeHandle.getParam('/electron_webrtc/video_device_label')
} catch (e) {
console.error('Failed to retreive parameters');
app.quit();
}
/** @member {String} */
const parameters = { webRtcServerUrl }; // videoDeviceLabel
console.log(parameters);
if (win) { win.webContents.send('parameters_response', parameters); }
/**
* Respond to the parameter_request event with the parameter
* @event parameters_response
* @type {object}
* @property {String} parameters - Parameters set in the launch file
*/
ipcMain.on('parameters_request', (event) => {
event.sender.send('parameters_response', parameters);
});
/**
* Fires after receiving data from ROS
* @event data
* @type {object}
* @property {String} data - Data received from ROS
*/
nodeHandle.subscribe('toElectron', std_msgs.String, (data) => {
hub.emit('data', data);
});
/** Advertise the fromElectron Node */
const publisher = nodeHandle.advertise('fromElectron', std_msgs.String);
/**
* After receiving teleop command from server, publish it to the fromElectron Node
* @event msg
* @type {object}
* @property {String} data - JSON string of the teleoperation command
*/
hub.on('msg', (data) => {
publisher.publish({ data });
});
/** advertise the operatorNavGoal node */
const patrolPublisher = nodeHandle.advertise('/electron/patrol', std_msgs.String);
/**
* After receiving a patrol from server, publish it to the operatorNavGoal Node
* @event patrol-plan
* @type {object}
* @property {String} patrolJsonString - JSON object containing the patrol.
*/
ipcMain.on('patrol-plan', (event, patrolJsonString) => {
patrolPublisher.publish({ data: patrolJsonString });
});
});
}
/**
* Calls to start the application
*/
startApp();
startNode();