diff --git a/.gitignore b/.gitignore index 3cdd63d..5171761 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ /bin/__pycache__ /asotr_csv/target/debug /asotr_csv/target/release +/asotr_csv/.vscode/ diff --git a/asotr_csv/.vimspector.json b/asotr_csv/.vimspector.json new file mode 100644 index 0000000..e4e7a95 --- /dev/null +++ b/asotr_csv/.vimspector.json @@ -0,0 +1,143 @@ +{ + "adapters": { + "custom-codelldb": { + "extends": "CodeLLDB", + "command": [ + "$HOME/Development/vimspector/CodeLLDB/build/adapter/codelldb", + "--port", "${unusedLocalPort}" + ] + }, + "CodeLLDB - StopOnEntry": { + "extends": "custom-codelldb", + "name": "CoHostingLLDB" + }, + "custom-cpptools": { + "extends": "vscode-cpptools", + "command": [ + "$HOME/Development/vimspector/MIEngine/bin/Debug/vscode/OpenDebugAD7" + ] + } + }, + "configurations": { + "Rust debug (gdb)": { + "adapter": "vscode-cpptools", + "configuration": { + "request": "launch", + "program": "${workspaceRoot}/target/debug/${workspaceRootBasename}", + "args": ["-d", "/home/danila/Danila/work/MVN/flight/data/"], + "cwd": "${workspaceRoot}", + "stopAtEntry": false, + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "rust-gdb", + "preLaunchTask": { + "type": "shell", + "command": "cargo build" + } + } + }, + "CodeLLDB-custom": { + "adapter": "custom-codelldb", + "configuration": { + "request": "launch", + "program": "${workspaceRoot}/test" + } + }, + "CodeLLDB": { + "adapter": "CodeLLDB", + "configuration": { + "request": "launch", + "expressions": "native", + "program": "${workspaceRoot}/test" + } + }, + "CodeLLDB-StopOnEntryFalse": { + "extends": "CodeLLDB", + "adapter": "CodeLLDB - StopOnEntry", + "configuration": { + "stopOnEntry": false + } + }, + "CodeLLDB-StopOnEntryTrue": { + "extends": "CodeLLDB-StopOnEntryFalse", + "configuration": { + "stopOnEntry": true + } + }, + "lldb-vscode": { + "adapter": "lldb-vscode", + "variables": { + "BUILDME": { + "shell": "g++ -o ${workspaceRoot}/test -g -std=c++17 ${workspaceRoot}/test_c.cpp" + } + }, + "configuration": { + "request": "launch", + "program": "${workspaceRoot}/test", + "stopAtEntry": true + } + }, + "cpptools (lldb)": { + "adapter": "vscode-cpptools", + "variables": { + "BUILDME": { + "shell": "g++ -o ${workspaceRoot}/test -g -std=c++17 ${workspaceRoot}/test_c.cpp" + }, + "arch": { + "shell": "uname -m" + } + }, + "configuration": { + "request": "launch", + "program": "${workspaceRoot}/test", + "stopAtEntry": true, + "MIMode": "lldb", + "MIDebuggerPath": "$HOME/.vim/vimspector-conf/gadgets/macos/vscode-cpptools/debugAdapters/lldb-mi/bin/lldb-mi", + "logging": { + "engineLogging": true + }, + "targetArchitecture": "${arch}" + } + }, + "cpptools (gdb)": { + "adapter": "vscode-cpptools", + "variables": { + "BUILDME": { + "shell": "echo ${workspaceRoot}/make all" + } + }, + "configuration": { + "request": "launch", + "program": "${workspaceRoot}/bin/main_debug", + "stopAtEntry": true, + "MIMode": "gdb" + } + }, + "cpptools-attach": { + "extends": "cpptools (lldb)", + "configuration": { + "request": "attach" + }, + "breakpoints": { + "exception": { + "cpp_throw": "", + "cpp_catch": "" + } + } + }, + "CodeLLDB-attach": { + "extends": "CodeLLDB", + "configuration": { + "request": "attach", + "pid": "${PickProcess(\"test\")}" + }, + "breakpoints": { + "exception": { + "cpp_throw": "", + "cpp_catch": "" + } + } + } + } +} diff --git a/asotr_csv/src/main.rs b/asotr_csv/src/main.rs index b9ef8ce..c4cf5cc 100644 --- a/asotr_csv/src/main.rs +++ b/asotr_csv/src/main.rs @@ -1,7 +1,7 @@ use clap::{Parser}; pub mod asotr_data { - use std::{fs::File, io::Read}; + use std::{fs::File, fs::read_to_string, io::Read}; use byteorder::{LittleEndian, ReadBytesExt}; use chrono::{DateTime, Utc}; use std::time::{SystemTime, UNIX_EPOCH, Duration}; @@ -57,7 +57,6 @@ pub mod asotr_data { date: String, time: String, data_type: AsotrDataType, - // kit: u8, } impl AsotrDataDesc { @@ -113,13 +112,30 @@ pub mod asotr_data { return Ok(out); } + + pub fn read_csv_data_(fname: &str) -> Result, String> { + match read_to_string(fname) { + Ok(content) => { + let mut result = Vec::new(); + for line in content.lines().skip(1) { + result.push(line.to_string()) + } + Ok(result) + } + Err(err) => Err(err.to_string()) + } + } + pub fn parse_data_dir(dir: &str, disp: bool) -> Result<(), String> { let mut data: Vec = Vec::new(); println!("parse data from directory: {}", dir); for (i, (pattern, fname)) in patterns_fnames_csv_data.iter().enumerate() { + let mut data1 = read_csv_data_(fname)?; let files = find_files_regex(dir, pattern)?; + data.append(&mut data1); + for elem in files { data.push(read_data(elem)?); } @@ -213,13 +229,6 @@ pub mod asotr_data { msg_prev)) }; - // let _kit = filename[30..32].parse::(); - // let kit = match &_kit { - // Ok(data) => data, - // Err(msg) => { return Err(format!("{}: expected digits in asotr kit part ({})", - // msg_prev, msg)); } - // }; - let _time_str_mks = fname[11..14].parse::(); let time_mks = match &_time_str_mks { Ok(data) => data, @@ -300,6 +309,8 @@ pub mod asotr_data { return Ok(()); } + + } #[derive(Parser, Debug)] diff --git a/asotr_csv/target/.rustc_info.json b/asotr_csv/target/.rustc_info.json index cebc56f..9ca4b6a 100644 --- a/asotr_csv/target/.rustc_info.json +++ b/asotr_csv/target/.rustc_info.json @@ -1 +1 @@ -{"rustc_fingerprint":14808889899039181664,"outputs":{"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\danil\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""},"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.87.0 (17067e9ac 2025-05-09)\nbinary: rustc\ncommit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359\ncommit-date: 2025-05-09\nhost: x86_64-pc-windows-msvc\nrelease: 1.87.0\nLLVM version: 20.1.1\n","stderr":""}},"successes":{}} \ No newline at end of file +{"rustc_fingerprint":2742313010855374649,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.83.0 (90b35a623 2024-11-26)\nbinary: rustc\ncommit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf\ncommit-date: 2024-11-26\nhost: x86_64-unknown-linux-gnu\nrelease: 1.83.0\nLLVM version: 19.1.1\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/danila/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}} \ No newline at end of file diff --git a/bin/asotr.py b/bin/asotr.py index aee746b..5f760eb 100644 --- a/bin/asotr.py +++ b/bin/asotr.py @@ -75,25 +75,31 @@ def flight_temperature_decode(cmd_string): def cmd_decode(cmd_string): decode = load_cmd_decode(fname_json_decode) - asotr_kit = 0; + asotr_kit = 0 msg_decode = '' out = '' - - if 'OK' in cmd_string: - return out cmd = cmd_string.split() - if len(cmd) > 5: - return out - if '1' in cmd[0]: asotr_kit = 1 elif '2' in cmd[0]: asotr_kit = 2 + if 'OK' in cmd_string: + return f'АСОТР{asotr_kit}: {cmd_string}' + + if len(cmd) > 5: + return f'АСОТР{asotr_kit}: {cmd_string}' + + if len(cmd) < 3: + return f'АСОТР{asotr_kit}: {cmd_string}' + msg_ = f'{cmd[1]} {cmd[2]}' - msg_decode = decode[msg_] + try: + msg_decode = f"({msg_}) {decode[msg_]}" + except KeyError as e: + return f'АСОТР{asotr_kit}: {cmd_string}' if (len(cmd) == 4): value = '' diff --git a/bin/asotr_csv b/bin/asotr_csv index ccca8a7..70cec67 100755 Binary files a/bin/asotr_csv and b/bin/asotr_csv differ diff --git a/bin/decode_asotr_cmd.json b/bin/decode_asotr_cmd.json index 3110220..579c030 100644 --- a/bin/decode_asotr_cmd.json +++ b/bin/decode_asotr_cmd.json @@ -1,88 +1,156 @@ { "write 0": "маркер начала сектора", + "read 0": "маркер начала сектора", "write 10": "Разрешение/блокировка работы мотора", + "read 10": "Разрешение/блокировка работы мотора", "write 11": "режим управления мотором", + "read 11": "режим управления мотором", "write 12": "направление вращения", + "read 12": "направление вращения", "write 14": "уставка защиты по току мотора кратковременная (мА)", + "read 14": "уставка защиты по току мотора кратковременная (мА)", "write 15": "уставка защиты по току мотора среднему за 20с (мА)", + "read 15": "уставка защиты по току мотора среднему за 20с (мА)", "write 16": "Время разгона мотора, секунд", + "read 16": "Время разгона мотора, секунд", "write 17": "Время останова мотора, секунд", + "read 17": "Время останова мотора, секунд", "write 18": "Номинальный ток мотора( мА)", + "read 18": "Номинальный ток мотора( мА)", "write 20": "СОТР1 режим управления каналом", + "read 20": "СОТР1 режим управления каналом", "write 21": "СОТР2 режим управления каналом", + "read 21": "СОТР2 режим управления каналом", "write 22": "СОТР3 режим управления каналом", + "read 22": "СОТР3 режим управления каналом", "write 23": "СОТР4 режим управления каналом", + "read 23": "СОТР4 режим управления каналом", "write 24": "СОТР5 режим управления каналом", + "read 24": "СОТР5 режим управления каналом", "write 25": "СОТР6 режим управления каналом", + "read 25": "СОТР6 режим управления каналом", "write 26": "СОТР1 уставка мощности в канале в %", + "read 26": "СОТР1 уставка мощности в канале в %", "write 27": "СОТР2 уставка мощности в канале в %", + "read 27": "СОТР2 уставка мощности в канале в %", "write 28": "СОТР3 уставка мощности в канале в %", + "read 28": "СОТР3 уставка мощности в канале в %", "write 29": "СОТР4 уставка мощности в канале в %", + "read 29": "СОТР4 уставка мощности в канале в %", "write 30": "СОТР5 уставка мощности в канале в %", + "read 30": "СОТР5 уставка мощности в канале в %", "write 31": "СОТР6 уставка мощности в канале в %", + "read 31": "СОТР6 уставка мощности в канале в %", "write 32": "Маска-разрешения работы каналов СОТР", + "read 32": "Маска-разрешения работы каналов СОТР", "write 50": "Уставка Kp ПИД-регулятора мотора", + "read 50": "Уставка Kp ПИД-регулятора мотора", "write 51": "Уставка Kd ПИД-регулятора мотора", + "read 51": "Уставка Kd ПИД-регулятора мотора", "write 52": "Уставка Ki ПИД-регулятора мотора", + "read 52": "Уставка Ki ПИД-регулятора мотора", "write 53": "заданная скорость вращения, об/мин", + "read 53": "заданная скорость вращения, об/мин", "write 55": "СОТР1 - уставка температуры канала", + "read 55": "СОТР1 - уставка температуры канала", "write 56": "СОТР2 - уставка температуры канала", + "read 56": "СОТР2 - уставка температуры канала", "write 57": "СОТР3 - уставка температуры канала", + "read 57": "СОТР3 - уставка температуры канала", "write 58": "СОТР4 - уставка температуры канала", + "read 58": "СОТР4 - уставка температуры канала", "write 59": "СОТР5 - уставка температуры канала", + "read 59": "СОТР5 - уставка температуры канала", "write 60": "СОТР6 - уставка температуры канала", + "read 60": "СОТР6 - уставка температуры канала", "write 61": "СОТР1 - уставка Kp ПИД-регулятора канала", + "read 61": "СОТР1 - уставка Kp ПИД-регулятора канала", "write 62": "СОТР2 - уставка Kp ПИД-регулятора канала", + "read 62": "СОТР2 - уставка Kp ПИД-регулятора канала", "write 63": "СОТР3 - уставка Kp ПИД-регулятора канала", + "read 63": "СОТР3 - уставка Kp ПИД-регулятора канала", "write 64": "СОТР4 - уставка Kp ПИД-регулятора канала", + "read 64": "СОТР4 - уставка Kp ПИД-регулятора канала", "write 65": "СОТР5 - уставка Kp ПИД-регулятора канала", + "read 65": "СОТР5 - уставка Kp ПИД-регулятора канала", "write 66": "СОТР6 - уставка Kp ПИД-регулятора канала", + "read 66": "СОТР6 - уставка Kp ПИД-регулятора канала", "write 67": "СОТР1 - уставка Kd ПИД-регулятора канала", + "read 67": "СОТР1 - уставка Kd ПИД-регулятора канала", "write 68": "СОТР2 - уставка Kd ПИД-регулятора канала", + "read 68": "СОТР2 - уставка Kd ПИД-регулятора канала", "write 69": "СОТР3 - уставка Kd ПИД-регулятора канала", + "read 69": "СОТР3 - уставка Kd ПИД-регулятора канала", "write 70": "СОТР4 - уставка Kd ПИД-регулятора канала", + "read 70": "СОТР4 - уставка Kd ПИД-регулятора канала", "write 71": "СОТР5 - уставка Kd ПИД-регулятора канала", + "read 71": "СОТР5 - уставка Kd ПИД-регулятора канала", "write 72": "СОТР6 - уставка Kd ПИД-регулятора канала", + "read 72": "СОТР6 - уставка Kd ПИД-регулятора канала", "write 73": "СОТР1 - уставка Ki ПИД-регулятора канала", + "read 73": "СОТР1 - уставка Ki ПИД-регулятора канала", "write 74": "СОТР2 - уставка Ki ПИД-регулятора канала", + "read 74": "СОТР2 - уставка Ki ПИД-регулятора канала", "write 75": "СОТР3 - уставка Ki ПИД-регулятора канала", + "read 75": "СОТР3 - уставка Ki ПИД-регулятора канала", "write 76": "СОТР4 - уставка Ki ПИД-регулятора канала", + "read 76": "СОТР4 - уставка Ki ПИД-регулятора канала", "write 77": "СОТР5 - уставка Ki ПИД-регулятора канала", + "read 77": "СОТР5 - уставка Ki ПИД-регулятора канала", "write 78": "СОТР6 - уставка Ki ПИД-регулятора канала", + "read 78": "СОТР6 - уставка Ki ПИД-регулятора канала", "write 79": "СОТР1 - уставка гистерезиса релейн. регулятора", + "read 79": "СОТР1 - уставка гистерезиса релейн. регулятора", "write 80": "СОТР2 - уставка гистерезиса релейн. регулятора", + "read 80": "СОТР2 - уставка гистерезиса релейн. регулятора", "write 81": "СОТР3 - уставка гистерезиса релейн. регулятора", + "read 81": "СОТР3 - уставка гистерезиса релейн. регулятора", "write 82": "СОТР4 - уставка гистерезиса релейн. регулятора", + "read 82": "СОТР4 - уставка гистерезиса релейн. регулятора", "write 83": "СОТР5 - уставка гистерезиса релейн. регулятора", + "read 83": "СОТР5 - уставка гистерезиса релейн. регулятора", "write 84": "СОТР6 - уставка гистерезиса релейн. регулятора", + "read 84": "СОТР6 - уставка гистерезиса релейн. регулятора", "write 85": "СОТР1 - уставка Ro термодатчика канала", + "read 85": "СОТР1 - уставка Ro термодатчика канала", "write 86": "СОТР2 - уставка Ro термодатчика канала", + "read 86": "СОТР2 - уставка Ro термодатчика канала", "write 87": "СОТР3 - уставка Ro термодатчика канала", + "read 87": "СОТР3 - уставка Ro термодатчика канала", "write 88": "СОТР4 - уставка Ro термодатчика канала", + "read 88": "СОТР4 - уставка Ro термодатчика канала", "write 89": "СОТР5 - уставка Ro термодатчика канала", + "read 89": "СОТР5 - уставка Ro термодатчика канала", "write 90": "СОТР6 - уставка Ro термодатчика канала", + "read 90": "СОТР6 - уставка Ro термодатчика канала", "write 91": "СОТР1 - уставка Alpha термодатчика канала", + "read 91": "СОТР1 - уставка Alpha термодатчика канала", "write 92": "СОТР2 - уставка Alpha термодатчика канала", + "read 92": "СОТР2 - уставка Alpha термодатчика канала", "write 93": "СОТР3 - уставка Alpha термодатчика канала", + "read 93": "СОТР3 - уставка Alpha термодатчика канала", "write 94": "СОТР4 - уставка Alpha термодатчика канала", + "read 94": "СОТР4 - уставка Alpha термодатчика канала", "write 95": "СОТР5 - уставка Alpha термодатчика канала", + "read 95": "СОТР5 - уставка Alpha термодатчика канала", "write 96": "СОТР6 - уставка Alpha термодатчика канала", - "func 1": "Перезапуск процессора МУП", - "func 2": "Перезапуск МУП через питание", - "func 3": "Запись текущих уставок в сектор I памяти FLASH", + "read 96": "СОТР6 - уставка Alpha термодатчика канала", + "func 1": "(func 1) Перезапуск процессора МУП", + "func 2": "(func 2) Перезапуск МУП через питание", + "func 3": "(func 3) Запись текущих уставок в сектор I памяти FLASH", "func 4": "Запись текущих уставок в сектор J памяти FLASH", "func 5": "Чтение уставок из сектора I памяти FLASH", "func 6": "Чтение уставок из сектора J памяти FLASH", "func 7": "Запуск мотора (разгон и поддержание скорости вращения)", "func 8": "Останов мотора (торможение и остановка)", "func 9": "Применить уставки СОТР из ОЗУ в алгоритме ПИД-регуляторов", - "status 1": "", - "status 2": "", - "status 3": "", - "status 4": "", - "status 5": "", - "status 6": "", - "status 7": "", - "status 8": "", - "status 9": "" + "status 2": "информация о моторе", + "status 3": "температура каналов АСОТР", + "status 4": "мощность в каналах АСОТР", + "status 5": "счетчики UART1", + "status 6": "счетчики UART2", + "status 7": "информация о FLASH", + "status 8": "уставки каналов АСОТР", + "status 9": "счетчик ошибок датчика холла и температура проц.", + "status 1": "версия ПО" } diff --git a/bin/plot_asotr_flight_all_for_Mikhail.py b/bin/plot_asotr_flight_all_for_Mikhail.py index d381ae7..8dc4db4 100644 --- a/bin/plot_asotr_flight_all_for_Mikhail.py +++ b/bin/plot_asotr_flight_all_for_Mikhail.py @@ -24,7 +24,7 @@ fname_pow = 'asotr' + asotr_kit + '_data_P.csv' pict_name = '../plots/' + 'ASOTR' + asotr_kit + '_flight_T_P_all' ox_dtime_format = '%Y.%m.%d' -legend=['БРД1', 'БРД2', 'БРД3', 'БРД4', 'плита МУП МВН, датчик1', 'плита МУП МВН, датчик 2'] +legend=['BRD1', 'BRD2', 'BRD3', 'BRD4', 'плита МУП МВН, датчик1', 'плита МУП МВН, датчик 2'] width=[1, 2, 1, 1, 1, 1] marker = ['-', '--', '-', '-', '-.', '-']; @@ -61,7 +61,7 @@ len_ = min(len_data) if xborders == False: begin = 0 - end = len_ - 1 + end = 320000 @@ -76,8 +76,8 @@ if plot_windows == 1: ax.tick_params(axis="both", width=1, labelsize=font) ax.grid(visible=True, linestyle = 'dotted') - ax.set_ylabel(r"Температура, $^\circ$C", fontsize=font) - ax.set_xlabel('Время', fontsize=font) + ax.set_ylabel(r"Temperature, $^\circ$C", fontsize=font) + ax.set_xlabel('Date', fontsize=font) ax.legend(fontsize=font) date_formatter = dates.DateFormatter(ox_dtime_format) @@ -100,8 +100,8 @@ elif plot_windows == 2: i += 1 ax3 = ax1.twinx() - ax3.plot(data_b['timestamp'][0:3400], data_b['beta_angle'][0:3400], marker[1], color='r', linewidth=width[1], label='угол Бета') - ax3.set_ylabel('Угол Бета', fontsize=font) + ax3.plot(data_b['timestamp'][0:3400], data_b['beta_angle'][0:3400], marker[1], color='r', linewidth=width[1], label='Beta angle') + ax3.set_ylabel('Beta angle', fontsize=font) ax3.tick_params(axis="y", width=1, labelsize=font) ax3.legend(fontsize=font, loc='upper right') @@ -113,8 +113,8 @@ elif plot_windows == 2: ax1.tick_params(axis="both", width=1, labelsize=font) ax1.grid(visible=True, linestyle = 'dotted') - ax1.set_ylabel(r"Температура, $^\circ$C", fontsize=font) - ax1.set_xlabel('Время', fontsize=font) + ax1.set_ylabel(r"Temperature, $^\circ$C", fontsize=font) + ax1.set_xlabel('Date', fontsize=font) ax1.legend(fontsize=font, loc='lower right') date_formatter = dates.DateFormatter(ox_dtime_format) @@ -129,7 +129,8 @@ elif plot_windows == 2: # date_formatter = dates.DateFormatter(ox_dtime_format) # ax2.xaxis.set_major_formatter(date_formatter) - plt.title('АСОТР ' + asotr_kit, fontsize=font) + # plt.title('automatic thermal control system ' + asotr_kit, fontsize=font) + # plt.title('Automated ' + asotr_kit, fontsize=font) plt.tight_layout() fig.savefig(pict_name) plt.show() diff --git a/bin/plot_flight_borders_article.sh b/bin/plot_flight_borders_article.sh new file mode 100755 index 0000000..76e7c7a --- /dev/null +++ b/bin/plot_flight_borders_article.sh @@ -0,0 +1,3 @@ +python3 plot_flight_borders_for_Mickhail.py -s ../data/asotr/ -c 100000 -a 01 -b 07.04.2025_08:00:00 -e 07.04.2025_17:00:00 -f 15 -w 1 -l 2 -g eng -t %d.%m.%Y + +python3 plot_flight_borders_for_Mickhail.py -s ../data/asotr/ -c 010000 -a 01 -b 25.06.2025_00:00:00 -e 24.07.2025_23:59:59 -f 15 -w 2 -l 2 -g eng -t %d.%m.%Y diff --git a/bin/plot_flight_borders_for_Mickhail.py b/bin/plot_flight_borders_for_Mickhail.py new file mode 100644 index 0000000..9cde562 --- /dev/null +++ b/bin/plot_flight_borders_for_Mickhail.py @@ -0,0 +1,228 @@ +import matplotlib.pyplot as plt +from matplotlib import dates +import argparse +import sys +from importlib import reload +sys.path.append('./') +import asotr +reload(asotr) +import pandas as pd + +def plot_asotr_borders(path_with_data, ch, asotr_kit, begin, end, font=16, + plot_windows=1, width_=2, lang='ru', time_format='%d.%m.%Y', + show_flag=False, cmd=0): + print_width = 20 + print_height = 12 + + channels = list(map(int, ch)) + pict_name = (f'../plots/reports/ASOTR{asotr_kit}_flight_T_P_{asotr.convert_to_str(channels)}_{begin[0:5].replace(".", "")}_{end[0:5].replace(".", "")}.png') + + plot_task = {"temp": 1, "temp_set": 1, "pow": 1} + # ox_dtime_format = "%d.%m.%Y" + ox_dtime_format = time_format + + if lang == 'ru': + legend = [ + "канал 1 (БРД1)", + "канал 2 (БРД2)", + "канал 3 (БРД3)", + "канал 4 (БРД4)", + "канал 5 (плита МУП МВН)", + "канал 6 (плита МУП МВН)", + ] + else: + legend = [ + "channel 1 (BRD1)", + "channel 2 (BRD2)", + "channel 3 (BRD3)", + "channel 4 (BRD4)", + "channel 5 (DCM landing place)", + "channel 6 (DCM landing place)", + ] + + if lang == 'ru': + legend_set = list(map(lambda x: x + " уставка", legend)) + else: + legend_set = list(map(lambda x: x + " setpoint", legend)) + width = [width_, width_, width_, width_, width_, width_] + width_set = [3, 3, 3, 3, 3, 3] + + marker = ["-", "-", "-.", "-", "-", "--"] + width_arr = [1, 0.5, 0.2, 0.1, 1, 1] + + # get from files and prepare data + start_date = begin.replace('_', ' ') + end_date = end.replace('_', ' ') + try: + data, data_dict = asotr.get_data(path_with_data, asotr_kit, start_date, end_date, 'minutes') + except Exception as e: + return + + if plot_windows == 1: + fig, ax = plt.subplots(figsize=(print_width, print_height), dpi=300) + + if plot_task["temp"] == 1: + for i in range(len(channels)): + if channels[i] == 1: + ax.plot(data_dict["time_temp"], + data_dict['temp'].iloc[:,i], + marker[i], + linewidth=width[i], + label=legend[i],) + + ax.tick_params(axis="both", width=1, labelsize=font) + ax.grid(visible=True, linestyle="dotted") + if lang == 'ru': + ax.set_ylabel(r"Температура, $^\circ$C", fontsize=font) + ax.set_xlabel("Время", fontsize=font) + else: + ax.set_ylabel(r"Temperature, $^\circ$C", fontsize=font) + ax.set_xlabel("Time", fontsize=font) + ax.legend(fontsize=font) + + date_formatter = dates.DateFormatter(ox_dtime_format) + ax.xaxis.set_major_formatter(date_formatter) + + plt.tight_layout() + fig.savefig(pict_name) + print(f'figure saved: {pict_name}') + if show_flag == True: + plt.show() + + elif plot_windows == 2: + + fig = plt.figure(figsize=(print_width, print_height), dpi=300) + ax1 = fig.add_subplot(2, 1, 1) + ax2 = fig.add_subplot(2, 1, 2, sharex=ax1) + + if cmd == '1': + try: + cmd_human = pd.read_csv('../data/cmd_asotr/cmd_human.csv', + delimiter=';', names=['timestamp', 'cmd']) + except Exception as e: + print(f'Error parsing file: {e}') + return + + max_temp = max(data_dict['temp'].iloc[:,1]) + min_temp = min(data_dict['temp'].iloc[:,1]) + # print(cmd_human) + step = 0 + for i, row in cmd_human.iterrows(): + row_time = row['timestamp'][0:len(row['timestamp']) - 4] + # print(row_time) + idx = asotr.find_best_time_idx(data_dict['time_temp'], + row_time, accuracy='minutes') + + # print(idx) + if idx != -1: + ax1.axvline(x = data_dict['time_temp'][idx], color='r', + linestyle='-.') + ax1.text(data_dict['time_temp'][idx], max_temp - step, row['cmd'], + rotation=45, va='bottom', fontsize=font) + step += (max_temp - min_temp)/20 + + if plot_task["temp"] == 1: + for i in range(len(channels)): + if channels[i] == 1: + ax1.plot(data_dict["time_temp"], + data_dict['temp'].iloc[:,i], + marker[i], + linewidth=width[i], + label=legend[i],) + + if plot_task["temp_set"] == 1: + for i in range(len(channels)): + if channels[i] == 1: + ax1.plot(data_dict["time_temp_set"], + data_dict['temp_set'].iloc[:,i], + marker[i], + linewidth=width_set[i], + label=legend_set[i],) + + if plot_task["pow"] == 1: + for i in range(len(channels)): + if channels[i] == 1: + ax2.plot(data_dict["time_pow"], + data_dict['pow'].iloc[:,i], + marker[i], + linewidth=width[i], + label=legend[i],) + + ax1.tick_params(axis="both", width=1, labelsize=font) + ax1.grid(visible=True, linestyle="dotted") + + if lang == 'ru': + ax1.set_ylabel(r"Температура, $^\circ$C", fontsize=font) + ax1.set_xlabel("Время", fontsize=font) + else: + ax1.set_ylabel(r"Temperature, $^\circ$C", fontsize=font) + ax1.set_xlabel("Time", fontsize=font) + + ax1.legend(fontsize=font) + + date_formatter = dates.DateFormatter(ox_dtime_format) + ax1.xaxis.set_major_formatter(date_formatter) + + ax2.tick_params(axis="both", width=1, labelsize=font) + ax2.grid(visible=True, linestyle="dotted") + if lang == 'ru': + ax2.set_ylabel("Мощность, %", fontsize=font) + ax2.set_xlabel("Время", fontsize=font) + else: + ax2.set_ylabel("Power, %", fontsize=font) + ax2.set_xlabel("Time", fontsize=font) + ax2.set_ylim(-5,105) + + ax2.legend(fontsize=font) + + date_formatter = dates.DateFormatter(ox_dtime_format) + ax2.xaxis.set_major_formatter(date_formatter) + + if lang == 'ru': + title = (f'работа АСОТР{asotr_kit} в период с {start_date[0:10]} по {end_date[0:10]} г.') + # else: + # title = (f'work of the ATCS{asotr_kit} in the period from {start_date[0:10]} to {end_date[0:10]} г.') + # fig.suptitle(title, fontsize=font) + plt.tight_layout() + fig.savefig(pict_name) + print(f'figure saved: {pict_name}') + if show_flag == True: + plt.show() + +if __name__ == '__main__': + argparser = argparse.ArgumentParser("plot_flight_borders.py") + + argparser.add_argument('-s', '--source', required=True, + help='type path with asotr csv data') + argparser.add_argument('-c', '--channel', required=True, + help='type channel (example: 000011)') + argparser.add_argument('-a', '--asotr', required=True, + help='type asotr kit (01 or 02)') + argparser.add_argument('-b', '--begin', required=True, + help='type begin date if dd.mm.YYYY format') + argparser.add_argument('-e', '--end', required=True, + help='type end date if dd.mm.YYYY format') + argparser.add_argument('-f', '--font', required=False, + help='type font size (from 1 to 30)') + argparser.add_argument('-d', '--cmd', required=False, + help='type display commands flag (0 or 1)') + argparser.add_argument('-p', '--plot', required=False, + help='display data in plot flag (0 or 1)') + argparser.add_argument('-w', '--plotwindows', required=False, + help='plot counts in window (1 or 2)') + argparser.add_argument('-l', '--linewidth', required=False, + help='line width in plot (1, 2, ...)') + argparser.add_argument('-t', '--timeformat', required=False, + help='specify the time format, for example: %d.%m.%Y') + argparser.add_argument('-g', '--language', required=False, + help='type language, for example: ru, eng') + + args = argparser.parse_args() + + # plot_asotr_borders(args.source, args.channel, args.asotr, args.begin, args.end, + # args.font, args.cmd, show_flag=args.plot, plot_windows=int(args.plotwindows), + # width_=int(args.linewidth), time_format = args.timeformat) + + plot_asotr_borders(args.source, args.channel, args.asotr, args.begin, args.end, + font=args.font, plot_windows=int(args.plotwindows), width_=int(args.linewidth), + lang=args.language, time_format=args.timeformat) diff --git a/bin/step_response.py b/bin/step_response.py index 11758ce..a8aeb1f 100644 --- a/bin/step_response.py +++ b/bin/step_response.py @@ -14,6 +14,9 @@ asotr_kit = 1 fname = f'../data/asotr/asotr0{asotr_kit}_data_T.csv' data = pd.read_csv(fname, sep=';', parse_dates=["timestamp"], date_format="%d.%m.%Y %H:%M:%S.%f") +# fname = f'../../python_cyclo/data/asotr0{asotr_kit}_data_T.csv' +# data = pd.read_csv(fname, sep=';', parse_dates=["timestamp"], date_format="%d.%m.%Y %H:%M:%S.%f") + # date = '20.03.2025' # period = '1 мин' # time_begin_orig = date + ' 17:10:11' @@ -45,42 +48,6 @@ data = pd.read_csv(fname, sep=';', parse_dates=["timestamp"], date_format="%d.%m # name_fig = 'step_response_KDI_20242403.png' -# interp = {'method': 'polynomial', 'order': 1} -# thermocycle_info = {'date': '01.04.2025', -# 'time_begin': ['01.04.2025 16:27:00', '01.04.2025 18:00:00'], -# 'duration_sec': 92*60, 'type': 'step'} -# cut_step_resp = {'time_step_begin': '01.04.2025 18:53:21', 'step_duration': 25*60} -# data_info = {'data': data, 'device': 'KDI', 'channel': 'ch1', 'period': '1 мин', -# 'find_accuracy': 'seconds'} -# name = f'{thermocycle_info["type"]}_response_{data_info["device"]}_{thermocycle_info["date"].replace(".","")}' -# plot_info = {'title': 'Реакция на ступенчатое воздействие', -# 'ox_dtime_format': "%H:%M:%S", 'legend_pos': ['upper left', 'lower left'], -# 'name_fig': f'{name}.png', 'font': 10} - - -fname = f'../../python_cyclo/data/asotr0{asotr_kit}_data_T.csv' -data = pd.read_csv(fname, sep=';', parse_dates=["timestamp"], date_format="%d.%m.%Y %H:%M:%S.%f") - -interp = {'method': 'polynomial', 'order': 1} - -data_info_list = [] -thermocycle_info_list = [] -cut_step_resp_list = [] - -data_info = {'data': data, 'device': 'КДИ', 'channel': 'ch1', 'period': '1 мин', - 'find_accuracy': 'seconds'} -thermocycle_info = {'date': '01.04.2025', - 'time_begin': ['01.04.2025 16:27:13', '01.04.2025 18:00:18'], - 'duration_sec': 92*60, 'type': 'step', 'type_ru': 'ступенчатое'} -cut_step_resp = {'time_step_begin': '01.04.2025 18:53:20', 'step_duration': 25*60} - -data_info_list.append(data_info) -thermocycle_info_list.append(thermocycle_info) -cut_step_resp_list.append(cut_step_resp) - - - - # interp = {'method': 'polynomial', 'order': 1} @@ -88,17 +55,36 @@ cut_step_resp_list.append(cut_step_resp) # thermocycle_info_list = [] # cut_step_resp_list = [] -# data_info = {'data': data, 'device': 'летный', 'channel': 'ch1', 'period': '1 мин', +# data_info = {'data': data, 'device': 'КДИ', 'channel': 'ch1', 'period': '1 мин', # 'find_accuracy': 'seconds'} -# thermocycle_info = {'date': '25.04.2025', -# 'time_begin': ['24.04.2025 22:46:32', '25.04.2025 00:19:33'], +# thermocycle_info = {'date': '01.04.2025', +# 'time_begin': ['01.04.2025 16:27:13', '01.04.2025 18:00:18'], # 'duration_sec': 92*60, 'type': 'step', 'type_ru': 'ступенчатое'} -# cut_step_resp = {'time_step_begin': '25.04.2025 01:18:01', 'step_duration': 30*60} +# cut_step_resp = {'time_step_begin': '01.04.2025 18:53:20', 'step_duration': 25*60} # data_info_list.append(data_info) # thermocycle_info_list.append(thermocycle_info) # cut_step_resp_list.append(cut_step_resp) + + +interp = {'method': 'polynomial', 'order': 1} + +data_info_list = [] +thermocycle_info_list = [] +cut_step_resp_list = [] + +data_info = {'data': data, 'device': 'летный', 'channel': 'ch1', 'period': '1 мин', + 'find_accuracy': 'seconds'} +thermocycle_info = {'date': '25.04.2025', + 'time_begin': ['24.04.2025 22:46:32', '25.04.2025 00:19:33'], + 'duration_sec': 92*60, 'type': 'step', 'type_ru': 'ступенчатое'} +cut_step_resp = {'time_step_begin': '25.04.2025 01:18:01', 'step_duration': 30*60} + +data_info_list.append(data_info) +thermocycle_info_list.append(thermocycle_info) +cut_step_resp_list.append(cut_step_resp) + # data_info = {'data': data, 'device': 'летный', 'channel': 'ch2', 'period': '1 мин', # 'find_accuracy': 'seconds'} # thermocycle_info = {'date': '25.04.2025', @@ -272,7 +258,7 @@ cut_step_resp_list.append(cut_step_resp) def get_step_response(data_info, thermocycle_info, cut_step_resp): name = f'{data_info["channel"]}_{thermocycle_info["type"]}_response_{data_info["device"]}_{thermocycle_info["date"].replace(".","")}' plot_info = {'title': 'Реакция на ' + thermocycle_info['type_ru'] + ' воздействие', - 'ox_dtime_format': "%H:%M", 'legend_pos': ['upper left', 'lower left'], + 'ox_dtime_format': "%H:%M:%S", 'legend_pos': ['upper left', 'lower left'], 'name_fig': f'../plots/response/{name}.png', 'font': 10} asotr.plot_step_response_in_thermocycle(data_info, thermocycle_info, interp, diff --git a/bin/tm_wheel_parser.py b/bin/tm_wheel_parser.py index ffee8c0..79f8484 100644 --- a/bin/tm_wheel_parser.py +++ b/bin/tm_wheel_parser.py @@ -14,7 +14,7 @@ ox_date_format = '%d.%m.%Y' path_itog_brd_data = '../data/brd_data/' pict_name = '../plots/' + 'MVN_wheel' -font = 16 +font = 18 class PathFileNotFound(Exception): @@ -112,48 +112,62 @@ if __name__ == "__main__": wheel_df = wheel_df.iloc[1::2] wheel_df['TIME_period'] = wheel_df['TIME'].diff() # print(wheel_df) - median_tdiff = wheel_df['TIME_period'].median() - # print(median_tdiff) + median_one = wheel_df['TIME_period'].median() ## discard outliers of the measured wheel period - wheel_df = wheel_df[ - (wheel_df['TIME_period'] > median_tdiff - border_clr_wheel) & - (wheel_df['TIME_period'] < median_tdiff + border_clr_wheel)] + wheel_df_clear = wheel_df[ + (wheel_df['TIME_period'] > median_one - border_clr_wheel) & + (wheel_df['TIME_period'] < median_one + border_clr_wheel)] - median = wheel_df['TIME_period'].median() + + wheel_df_clear1 = wheel_df[ + (wheel_df['TIME_period'] > median_one - 0.3) & + (wheel_df['TIME_period'] < median_one + 0.3)] + + + std = wheel_df_clear['TIME_period'].std(ddof=1) + print(median_one) + print(std) - rows, cols = wheel_df.shape - median = pd.Series([median] * rows) + rows, cols = wheel_df_clear.shape + median = pd.Series([median_one] * rows) + date_format = dates.DateFormatter(ox_date_format) datetime_format = dates.DateFormatter(ox_dtime_format) - fig, axes = plt.subplots(3, 1, figsize=(18, 20), dpi=300, height_ratios=[1, 1, 1]) + fig, axes = plt.subplots(2, 1, figsize=(20, 15), dpi=300, height_ratios=[1, 1]) - axes[0].plot(wheel_df['timestamp'], wheel_df['TIME_period'], '.', - markersize=5) - axes[0].plot(wheel_df['timestamp'], median) + axes[0].plot(wheel_df_clear['timestamp'], + wheel_df_clear['TIME_period'], '.', markersize=5) + axes[0].plot(wheel_df_clear['timestamp'], median) axes[0].set_title("") - axes[0].set_xlabel("Время (ДД.MM.ГГГГ)", fontsize=font) - axes[0].set_ylabel("Полупериод, сек", fontsize=font) + axes[0].set_xlabel("Date", fontsize=font) + axes[0].set_ylabel("Period, sec", fontsize=font) axes[0].grid(True) axes[0].xaxis.set_major_formatter(date_format) axes[0].tick_params(axis="both", width=1, labelsize=font) - axes[1].plot(wheel_df['timestamp'][0:400], wheel_df['TIME_period'][0:400], '.', markersize=10) - axes[1].set_title("") - axes[1].set_xlabel("Время (ЧЧ:ММ)", fontsize=font) - axes[1].set_ylabel("Полупериод, сек", fontsize=font) - axes[1].grid(True) - axes[1].xaxis.set_major_formatter(datetime_format) - axes[1].tick_params(axis="both", width=1, labelsize=font) + # axes[1].plot(wheel_df_clear['timestamp'][0:400], + # wheel_df_clear['TIME_period'][0:400], '.', markersize=10) + # axes[1].set_title("") + # axes[1].set_xlabel("Время (ЧЧ:ММ)", fontsize=font) + # axes[1].set_ylabel("Период, сек", fontsize=font) + # axes[1].grid(True) + # axes[1].xaxis.set_major_formatter(datetime_format) + # axes[1].tick_params(axis="both", width=1, labelsize=font) - sns.histplot(wheel_df['TIME_period'], kde=False, bins=300, ax=axes[2], color='red') - axes[2].set_title("") - axes[2].set_xlabel("Полупериод, сек", fontsize=font) - axes[2].set_ylabel("Частота встречаемости", fontsize=font) - axes[2].grid(True) - axes[2].tick_params(axis="both", width=1, labelsize=font) + sns.histplot(wheel_df_clear1['TIME_period'], kde=False, bins=300, ax=axes[1], color='red') + # sns.kdeplot(wheel_df_clear1['TIME_period'], fill=True, ax=axes[2], color='red') + # axes[2].axvline(median_one, color='red', linestyle='--', label='Медианное') + axes[1].axvline(median_one - 3*std, color='blue', linestyle='--', label='3σ') + axes[1].axvline(median_one + 3*std, color='blue', linestyle='--') + axes[1].set_title("") + axes[1].set_xlabel("Period, sec", fontsize=font) + axes[1].set_ylabel("Number of measurements", fontsize=font) + axes[1].grid(True) + axes[1].legend(fontsize=font) + axes[1].tick_params(axis="both", width=1, labelsize=font) fig.savefig(pict_name)