123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- import {app, BrowserWindow, ipcMain, dialog} from 'electron';
- import {exec, spawn} from 'child_process';
- import path from 'path';
- import {fileURLToPath} from 'url';
- import fs from 'fs';
- import axios from 'axios';
- import {resolve} from "node:dns";
- import {execSync} from "node:child_process";
- const __filename = fileURLToPath(import.meta.url);
- const __dirname = path.dirname(__filename);
- function createWindow() {
- const win = new BrowserWindow({
- width: 800,
- height: 600,
- webPreferences: {
- preload: path.join(__dirname, 'preload.js'), // 确保路径正确
- contextIsolation: true,
- enableRemoteModule: false,
- nodeIntegration: false,
- }
- });
- win.webContents.openDevTools(); // 打开开发者工具进行调试
- win.loadURL('http://localhost:5173'); // 开发环境
- // win.loadURL('http://36.110.106.156:81'); // 生产环境
- console.log('Window created and URL loaded');
- }
- app.whenReady().then(createWindow);
- app.on('window-all-closed', () => {
- if (process.platform !== 'darwin') {
- app.quit();
- }
- });
- app.on('ready', () => {
- // 异步
- ipcMain.on('run-simulation', (event, {obstacle_flag, default_start_flag, default_end_flag, start_point, end_point}) => {
- const command = 'bash /home/cicv/work/pji_desktop/simulation/run_simulation.sh ' + obstacle_flag + ' ' + default_start_flag + ' ' + default_end_flag +
- ' ' + start_point + ' ' + end_point;
- console.log('command:', command);
- exec(command, (error, stdout, stderr) => {
- if (error) {
- console.error(`exec error: ${error}`);
- event.reply('run-simulation-response', { success: false, message: error.message });
- return;
- } else {
- console.log(`stdout: ${stdout}`);
- console.error(`stderr: ${stderr}`);
- event.reply('run-simulation-response', { success: true, message: 'Run simulation successfully' });
- }
- });
- });
- })
- app.on('activate', () => {
- if (BrowserWindow.getAllWindows().length === 0) {
- createWindow();
- }
- });
- // ------------- 进程通信 -------------
- ipcMain.on('open-gazebo', (event, arg) => {
- console.log('Received open-gazebo event');
- exec('gazebo', (error, stdout, stderr) => {
- if (error) {
- console.error(`exec error: ${error}`);
- return;
- }
- console.log(`stdout: ${stdout}`);
- console.error(`stderr: ${stderr}`);
- });
- });
- ipcMain.on('open-rviz', (event, arg) => {
- console.log('Received open-rviz event');
- exec('rviz', (error, stdout, stderr) => {
- if (error) {
- console.error(`exec error: ${error}`);
- return;
- }
- console.log(`stdout: ${stdout}`);
- console.error(`stderr: ${stderr}`);
- });
- });
- ipcMain.on('close-gazebo', (event, arg) => {
- console.log('Received close-gazebo event');
- exec('pkill -f gzserver & pkill -f gzclient', (error, stdout, stderr) => {
- if (error) {
- console.error(`exec error: ${error}`);
- return;
- }
- console.log(`stdout: ${stdout}`);
- console.error(`stderr: ${stderr}`);
- });
- });
- ipcMain.on('close-rviz', (event, arg) => {
- console.log('Received close-rviz event');
- exec('pkill -f rviz', (error, stdout, stderr) => {
- if (error) {
- console.error(`exec error: ${error}`);
- return;
- }
- console.log(`stdout: ${stdout}`);
- console.error(`stderr: ${stderr}`);
- });
- });
- ipcMain.handle('dialog:open', async (event, options = {}) => {
- const result = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow() || BrowserWindow.getAllWindows()[0], options);
- return result.canceled ? null : result.filePaths;
- });
- ipcMain.on('docker-import', (event, filePath, tag) => {
- const command = 'bash /home/cicv/work/pji_desktop/docker_import/run_docker_import.sh ' + filePath + ' pji_nav ' + tag
- console.log('导入算法镜像文件:', command);
- exec(command, (error, stdout, stderr) => {
- if (error) {
- console.error(`exec error: ${error}`);
- event.reply('docker-import-response', { success: false, message: error.message });
- return;
- } else {
- console.log(`stdout: ${stdout}`);
- console.error(`stderr: ${stderr}`);
- event.reply('docker-import-response', { success: true, message: 'Docker image imported successfully' });
- }
- });
- });
- ipcMain.on('generate-world', (event, {rosbag_path}) => {
- const command = 'bash /home/cicv/work/pji_desktop/simulation/generate_world.sh ' + rosbag_path
- console.log('World generation command:', command);
- exec(command, (error, stdout, stderr) => {
- if (error) {
- console.error(`exec error: ${error}`);
- event.reply('generate-world-response', { success: false, message: error.message });
- } else {
- console.log(`stdout: ${stdout}`);
- console.error(`stderr: ${stderr}`);
- event.reply('generate-world-response', { success: true, message: 'World generated successfully' });
- }
- });
- });
- ipcMain.on('start-container', (event, {zip_file_path, image_name, container_name}) => {
- // 使用 spawn 启动脚本
- const serviceProcess = spawn('bash', ["/home/cicv/work/pji_desktop/simulation/data_preparation.sh", zip_file_path], { detached: true });
- // 设置为后台进程
- serviceProcess.unref();
- // 监听输出
- serviceProcess.stdout.on('data', (data) => {
- console.log(`第一个脚本的输出: ${data}`);
- // 根据第一个脚本的输出判断其是否准备好
- if (data.toString().includes('Data preparation done')) {
- startSecondScript();
- }
- });
- // 监听错误
- serviceProcess.stderr.on('data', (data) => {
- console.error(`执行第一个脚本时出错: ${data}`);
- });
- // 监听关闭
- serviceProcess.on('close', (data) => {
- console.log(`第一个脚本已关闭: ${data}`);
- });
- function startSecondScript() {
- let command = "bash /home/cicv/work/pji_desktop/simulation/start_container.sh " + image_name + " " + container_name
- // 启动第二个脚本
- const script2 = exec(command, (error, stdout, stderr) => {
- if (error) {
- console.error(`执行第二个脚本时出错: ${error}`);
- event.sender.send('start-container-response', { success: false, output: error });
- return;
- }
- console.log(`第二个脚本的输出: ${stdout}`);
- event.sender.send('start-container-response', { success: true, output: stdout });
- });
- script2.on('exit', (code) => {
- console.log(`第二个脚本已退出,退出码: ${code}`);
- });
- }
- });
- // 同步
- // ipcMain.handle('run-simulation', (event, {obstacle_flag, default_start_flag, default_end_flag, start_point, end_point}) => {
- // const command = 'bash /home/cicv/work/pji_desktop/simulation/run_simulation.sh ' + obstacle_flag + ' ' + default_start_flag + ' ' + default_end_flag +
- // ' ' + start_point + ' ' + end_point;
- // console.log('command:', command);
- //
- // // 同步
- // try {
- // const output = execSync(command)
- // console.log("output", output.toString());
- // return { success: false, message: error.message }
- // } catch (error) {
- // console.error(`exec error: ${error}`);
- // return { success: true, message: 'Run simulation successfully' }
- // }
- // });
- ipcMain.handle('download-file', async (event, { url, fileName, savePath, overwriteFlag }) => {
- try {
- // console.log("url", url)
- // console.log("response", response)
- const filePath = path.join(savePath, fileName);
- // 查找文件是否存在
- const fileExists = fs.existsSync(filePath)
- if (fileExists && !overwriteFlag) { // 已存在且不覆盖
- return {success: true, filePath}
- } else { // 不存在
- const response = await axios.get(url, {responseType: 'stream'});
- // 写入文件
- const writer = fs.createWriteStream(filePath);
- return new Promise((resolve, reject) => {
- response.data.pipe(writer);
- let error = null;
- writer.on('error', err => {
- error = err;
- writer.close();
- reject(err);
- });
- writer.on('close', () => {
- if (!error) {
- resolve({success: true, filePath}); // 返回成功信息
- } else {
- reject({success: false, error: error.message}); // 返回错误信息
- }
- });
- });
- }
- } catch (error) {
- // console.error('下载文件出错:', error);
- throw error;
- }
- });
- // 监听从渲染进程传来的删除文件请求
- ipcMain.on('delete-file', (event, {fileName, savePath}) => {
- const filePath = path.join(savePath, fileName);
- // 检查文件是否存在
- if (fs.existsSync(filePath)) {
- // 文件存在,尝试删除
- fs.unlink(filePath, (err) => {
- if (err) {
- event.reply('delete-file-response', { success: false, message: err.message });
- } else {
- event.reply('delete-file-response', { success: true, message: 'File deleted successfully' });
- }
- });
- } else {
- // 文件不存在
- event.reply('delete-file-response', { success: false, message: 'File does not exist' });
- }
- });
|