|
@@ -38,25 +38,10 @@ app.on('window-all-closed', () => {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
-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('ready', () => {
|
|
|
+// // 异步
|
|
|
+//
|
|
|
+// })
|
|
|
|
|
|
app.on('activate', () => {
|
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
@@ -66,63 +51,144 @@ app.on('activate', () => {
|
|
|
|
|
|
|
|
|
// ------------- 进程通信 -------------
|
|
|
-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.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('open-rviz', (event, arg) => {
|
|
|
- console.log('Received open-rviz event');
|
|
|
- exec('rviz', (error, stdout, stderr) => {
|
|
|
- if (error) {
|
|
|
- console.error(`exec error: ${error}`);
|
|
|
- return;
|
|
|
+// 下载文件
|
|
|
+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}); // 返回错误信息
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
}
|
|
|
- console.log(`stdout: ${stdout}`);
|
|
|
- console.error(`stderr: ${stderr}`);
|
|
|
- });
|
|
|
+ } catch (error) {
|
|
|
+ // console.error('下载文件出错:', error);
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
-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('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' });
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
+// 上传文件
|
|
|
+ipcMain.on('upload-file', async (event, {filePath, uploadUrl}) => {
|
|
|
+ if (!fs.existsSync(filePath)) {
|
|
|
+ console.log("File does not exist");
|
|
|
+ event.reply('upload-file-response', {success: false, message: 'File does not exist'});
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 读取文件
|
|
|
+ // fs.readFile(filePath, async (err, data) => {
|
|
|
+ // if(err) {
|
|
|
+ // console.log("Error reading file:", err);
|
|
|
+ // event.reply('upload-file-response', { success: false, message: err.message });
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // // 创建formData对象
|
|
|
+ // const formData = new FormData();
|
|
|
+ // formData.append('file', new Blob([data]), path.basename(filePath));
|
|
|
+ //
|
|
|
+ // try {
|
|
|
+ // // 使用axios上传文件
|
|
|
+ // const response = await axios.post(uploadUrl, formData, {
|
|
|
+ // headers: {
|
|
|
+ // 'Content-Type': 'multipart/form-data'
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ // console.log('response', response)
|
|
|
+ // event.reply('upload-file-response', { success: true, message: 'File uploaded successfully' });
|
|
|
+ // } catch (err) {
|
|
|
+ // console.log("Error uploading file:", err);
|
|
|
+ // event.reply('upload-file-response', { success: false, message: err.message });
|
|
|
+ // }
|
|
|
+ // })
|
|
|
|
|
|
-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;
|
|
|
+ try {
|
|
|
+ const result = await uploadFile(filePath, uploadUrl);
|
|
|
+ console.log("result", result);
|
|
|
+ if (result.status) {
|
|
|
+ event.reply('upload-file-response', { success: true, message: 'File uploaded successfully', details: result.details });
|
|
|
+ } else {
|
|
|
+ event.reply('upload-file-response', { success: false, message: 'Error uploading file', details: '' });
|
|
|
}
|
|
|
- console.log(`stdout: ${stdout}`);
|
|
|
- console.error(`stderr: ${stderr}`);
|
|
|
- });
|
|
|
+ } catch (err) {
|
|
|
+ event.reply('upload-file-response', { success: false, message: err.message, details: '' });
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
+async function uploadFile(filePath, uploadUrl) {
|
|
|
|
|
|
-ipcMain.handle('dialog:open', async (event, options = {}) => {
|
|
|
- const result = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow() || BrowserWindow.getAllWindows()[0], options);
|
|
|
- return result.canceled ? null : result.filePaths;
|
|
|
-});
|
|
|
+ const data = fs.readFileSync(filePath)
|
|
|
+ // 创建formData对象
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append('file', new Blob([data]), path.basename(filePath));
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 使用axios上传文件
|
|
|
+ const response = await axios.post(uploadUrl, formData, {
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'multipart/form-data'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // console.log('response', response.data)
|
|
|
|
|
|
+ return response.data
|
|
|
+ } catch (err) {
|
|
|
+ console.log("Error uploading file:", err);
|
|
|
+ return { status: false, code: '', message: '上传stl文件失败', details: '' };
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
+// 导入算法镜像
|
|
|
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('Docker import command:', command);
|
|
@@ -139,7 +205,7 @@ ipcMain.on('docker-import', (event, filePath, tag) => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
-
|
|
|
+// 生成world
|
|
|
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);
|
|
@@ -155,7 +221,7 @@ ipcMain.on('generate-world', (event, {rosbag_path}) => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
-
|
|
|
+// 启动仿真环境
|
|
|
ipcMain.on('start-container', (event, {zip_file_path, image_name, container_name}) => {
|
|
|
|
|
|
// 使用 spawn 启动脚本
|
|
@@ -203,115 +269,87 @@ ipcMain.on('start-container', (event, {zip_file_path, image_name, container_name
|
|
|
}
|
|
|
});
|
|
|
|
|
|
-// 同步
|
|
|
-// 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 });
|
|
|
+// 执行仿真
|
|
|
+ipcMain.on('run-simulation', (event, {random_flag, count, obstacle_flag, default_start_flag, default_end_flag, start_point, end_point}) => {
|
|
|
+ const command = 'bash /home/cicv/work/pji_desktop/simulation/run_simulation.sh ' + random_flag + ' ' + count + ' ' + 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 });
|
|
|
+ } else {
|
|
|
+ console.log(`stdout: ${stdout}`);
|
|
|
+ console.error(`stderr: ${stderr}`);
|
|
|
+ if (stdout.toString().includes('Evaluation finished')) { // 判断结束标志
|
|
|
+ event.reply('run-simulation-response', { success: true, message: 'Run simulation successfully' });
|
|
|
} else {
|
|
|
- event.reply('delete-file-response', { success: true, message: 'File deleted successfully' });
|
|
|
+ event.reply('run-simulation-response', { success: false, message: 'Error running simulation' });
|
|
|
}
|
|
|
- });
|
|
|
- } else {
|
|
|
- // 文件不存在
|
|
|
- event.reply('delete-file-response', { success: false, message: 'File does not exist' });
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-// 上传文件
|
|
|
-ipcMain.on('upload-file', (event, {filePath, uploadUrl}) => {
|
|
|
- if (!fs.existsSync(filePath)) {
|
|
|
- console.log("File does not exist");
|
|
|
- event.reply('upload-file-response', { success: false, message: 'File does not exist' });
|
|
|
- return;
|
|
|
- }
|
|
|
- // 读取文件
|
|
|
- fs.readFile(filePath, async (err, data) => {
|
|
|
- if(err) {
|
|
|
- console.log("Error reading file:", err);
|
|
|
- event.reply('upload-file-response', { success: false, message: err.message });
|
|
|
- return;
|
|
|
}
|
|
|
+ });
|
|
|
+});
|
|
|
|
|
|
- // 创建formData对象
|
|
|
- const formData = new FormData();
|
|
|
- formData.append('file', new Blob([data]), path.basename(filePath));
|
|
|
+// 读取并上传算法评价结果
|
|
|
+ipcMain.handle('process-evaluation-files', async (event, {N, equipmentNo, sceneNo}) => {
|
|
|
+ const result = []
|
|
|
+ const evalDir = "/home/cicv/work/pji_desktop/simulation/data/evaluation";
|
|
|
+ const bagDir = "/home/cicv/work/pji_desktop/simulation/data/record_bag";
|
|
|
+ console.log('N', N)
|
|
|
+ // 记录时间戳
|
|
|
+ const timeStamp = Date.now()
|
|
|
+ console.log("timeStamp", timeStamp);
|
|
|
+
|
|
|
+ // 遍历评价结果文件夹,读取并上传相关数据
|
|
|
+ for (let i = 1; i <= N; i++) {
|
|
|
+ const subDir = path.join(evalDir, `${i}/result`);
|
|
|
+ console.log("subDir", subDir);
|
|
|
+ // 文件路径 - report.json
|
|
|
+ const jsonFilePath = path.join(subDir, "report.json");
|
|
|
+ console.log("jsonFilePath", jsonFilePath);
|
|
|
+ // 文件路径 - report.pdf
|
|
|
+ const pdfFilePath = path.join(subDir, "report.pdf");
|
|
|
+ console.log("pdfFilePath", pdfFilePath);
|
|
|
+ // 文件路径 - test-${i}.bag
|
|
|
+ const bagFilePath = path.join(bagDir, `test-${i}.bag`);
|
|
|
+ console.log("bagFilePath", bagFilePath);
|
|
|
+
|
|
|
+ const uploadPdfUrl = "http://127.0.0.1:8888/simulation/upload/pdf?equipmentNo=" + equipmentNo + "&sceneNo=" + sceneNo +
|
|
|
+ "&timeStamp=" + timeStamp + "&round=" + i;
|
|
|
+
|
|
|
+ const uploadBagUrl = "http://127.0.0.1:8888/simulation/upload/bag?equipmentNo=" + equipmentNo + "&sceneNo=" + sceneNo +
|
|
|
+ "&timeStamp=" + timeStamp + "&round=" + i;
|
|
|
|
|
|
try {
|
|
|
- // 使用axios上传文件
|
|
|
- const response = await axios.post(uploadUrl, formData, {
|
|
|
- headers: {
|
|
|
- 'Content-Type': 'multipart/form-data'
|
|
|
- }
|
|
|
+ // 读取json文件
|
|
|
+ const jsonData = fs.readFileSync(jsonFilePath, "utf-8");
|
|
|
+ const parsedData = JSON.parse(jsonData);
|
|
|
+ console.log("parsedData", parsedData);
|
|
|
+ // 上传pdf文件
|
|
|
+ const uploadPdfResult = await uploadFile(pdfFilePath, uploadPdfUrl);
|
|
|
+ console.log("uploadPdfResult", uploadPdfResult);
|
|
|
+ if (!uploadPdfResult.status) { break}
|
|
|
+ // 上传bag文件
|
|
|
+ const uploadBagResult = await uploadFile(bagFilePath, uploadBagUrl);
|
|
|
+ console.log("uploadBagUrl", uploadBagUrl);
|
|
|
+ if (!uploadBagResult.status) { break}
|
|
|
+ // 整合结果
|
|
|
+ result.push({
|
|
|
+ "round": i,
|
|
|
+ "jsonData": parsedData,
|
|
|
+ "uploadPdfKey": uploadPdfResult.details,
|
|
|
+ "uploadBagKey": uploadBagResult.details,
|
|
|
+ "timeStamp": timeStamp
|
|
|
})
|
|
|
- console.log('response', response)
|
|
|
- event.reply('upload-file-response', { success: true, message: 'File uploaded successfully' });
|
|
|
- } catch (err) {
|
|
|
- console.log("Error uploading file:", err);
|
|
|
- event.reply('upload-file-response', { success: false, message: err.message });
|
|
|
+ } catch (error) {
|
|
|
+ console.log("error", error);
|
|
|
+ return { success: false, message: "Error uploading evaluation results", data: [] }
|
|
|
}
|
|
|
- })
|
|
|
-});
|
|
|
+ }
|
|
|
+ // 判断数据上传是否完整
|
|
|
+ if (result.length === N) {
|
|
|
+ return { success: true, message: "Evaluation results uploaded successfully", data: result }
|
|
|
+ } else {
|
|
|
+ return { success: false, message: "Error uploading evaluation results", data: [] }
|
|
|
+ }
|
|
|
+})
|