Compare commits

...

5 Commits

18 changed files with 116 additions and 16 deletions

View File

@ -80,8 +80,8 @@
0.02
],
"distance_l_2": [
0.033,
0.033,
0.0275,
0.03,
0.033,
0.033,
0.033,
@ -176,7 +176,7 @@
0.5
],
"object_thickness": [
0.0,
0.0045,
0.0045,
0.0045,
0.0045,

View File

@ -55,5 +55,8 @@
],
"UML_time_scaler": [
1000.0
],
"Range ME, mm": [
115.0
]
}

View File

@ -8,9 +8,13 @@ class Controller(BaseController):
signal_widgets = pyqtSignal(list)
signal_settings = pyqtSignal(list)
signal_monitor = pyqtSignal(str)
def send_widgets(self, widgets: list[QWidget]) -> None:
self.signal_widgets.emit(widgets)
def push_settings(self, settings: list[dict]) -> None:
self.signal_settings.emit(settings)
def open_custom_file (self, filepath: str) -> None:
self.signal_monitor.emit(filepath)

View File

@ -47,5 +47,9 @@ class DirectoryMonitor(BaseDirectoryMonitor):
else:
logger.info(f"Failed pushing {str(all_files)}")
def custom_dir_extract(self, dict_path:str ):
files = os.listdir(dict_path)
if files is not None:
all_files = [os.path.join(dict_path, file) for file in files]
self._mediator.notify(self, all_files)

View File

@ -43,6 +43,10 @@ class PassportFormer(BasePointPassportFormer):
system_settings = {key: value[0] for key, value in self._params[1].items()}
tesla_time = sum(self._params[0].get("Tesla summary time", []))
useful_data = {"tesla_time": tesla_time,
"range_ME": system_settings["Range ME, mm"],
"k_hardness": system_settings["k_hardness_1"]
}
points_pocket = []
@ -59,7 +63,7 @@ class PassportFormer(BasePointPassportFormer):
}
params_list = [operator_settings, system_settings]
cache_key = self._generate_cache_key(params_list)
if cache_key in self._ideal_data_cashe:
if cache_key in self._ideal_data_cashe :
ideal_data = self._ideal_data_cashe[cache_key]
print(f"Cache hit")
else:
@ -69,9 +73,12 @@ class PassportFormer(BasePointPassportFormer):
idx = i+1 if idx_shift else i
point_timeframe = [events[self._stages[0]][0][i], events[self._stages[-1]][1][idx]]
point_events = {key: [value[0][i], value[1][i]] for key, value in events.items()}
useful_p_data = {"thickness": operator_settings["object_thickness"],
"L2": operator_settings["distance_l_2"],
"force": operator_settings["force_target"]}
points_pocket.append([point_timeframe, ideal_data, point_events])
return dataframe, points_pocket, tesla_time
points_pocket.append([point_timeframe, ideal_data, point_events, useful_p_data])
return dataframe, points_pocket, useful_data
def update_settings(self, params: list[dict, dict]):
self._params = params

View File

@ -14,6 +14,7 @@ class MainWindow(BaseMainWindow):
self.initUI()
self.set_style(self)
self.settings_button.clicked.connect(self._show_settings)
self.select_dir_button.clicked.connect(self._select_dir)
self.operSettings = settingsWindow("params/operator_params.json", 'Operator', self._updater_trigger)
self.sysSettings = settingsWindow("params/system_params.json", 'System', self._updater_trigger)
@ -23,9 +24,17 @@ class MainWindow(BaseMainWindow):
self.tabWidget.tabCloseRequested.connect(self._close_tab)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.tabWidget)
self.settings_button = QtWidgets.QPushButton("Show settings")
self.settings_button.setFixedWidth(160)
layout.addWidget(self.settings_button)
self.select_dir_button = QtWidgets.QPushButton("Open directory")
self.select_dir_button.setFixedWidth(175)
button_layout = QtWidgets.QHBoxLayout()
button_layout.setSpacing(2)
button_layout.addWidget(self.settings_button)
button_layout.addWidget(self.select_dir_button)
layout.addLayout(button_layout)
self.setLayout(layout)
def show_plot_tabs(self, plot_widgets: list[QtWidgets.QWidget]) -> None:
@ -63,6 +72,10 @@ class MainWindow(BaseMainWindow):
def _close_tab(self, index:int) -> None:
self.tabWidget.removeTab(index)
def _select_dir(self):
folder_path = QtWidgets.QFileDialog.getExistingDirectory(self, 'Select directory', "")
if folder_path:
self._controller.open_custom_file(folder_path)

View File

@ -1,5 +1,6 @@
import pandas as pd
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QGraphicsRectItem
import copy
import pyqtgraph as pg
@ -192,15 +193,41 @@ class PlotWidget(BasePlotWidget):
layout.addWidget(performance_label)
performance_label.update()
def _mirror_shift_data(self,
valid_str: str,
signals: list[dict],
dataframe: pd.DataFrame,
shift: float) -> pd.DataFrame:
keys = dataframe.keys()
for signal in signals:
if valid_str in signal["name"] and signal["name"] in keys:
dataframe[signal["name"]] = dataframe[signal["name"]].apply(lambda x: shift-x)
return dataframe
def _shift_data(self,
valid_str: str,
signals: list[dict],
dataframe: pd.DataFrame,
shift: float) -> pd.DataFrame:
keys = dataframe.keys()
for signal in signals:
if valid_str in signal["name"] and signal["name"] in keys:
dataframe[signal["name"]] = dataframe[signal["name"]].apply(lambda x: x + shift)
return dataframe
def _build_widget(self, data: list[Any]) -> QWidget:
"""
Собирает графический виджет для одного набора данных.
Параметр `data` предполагается списком: [dataframe, points_pocket, tesla_time].
Параметр `data` предполагается списком: [dataframe, points_pocket, useful_data].
"""
widget = QWidget()
layout = QVBoxLayout(widget)
dataframe, points_pocket, tesla_time = data
dataframe, points_pocket, useful_data = data
tesla_time = useful_data["tesla_time"]
range_ME = useful_data["range_ME"]
k_hardness = useful_data["k_hardness"]
dataframe_headers = dataframe.columns.tolist()
for widget_num, (channel, description) in enumerate(self._plt_channels.items()):
@ -210,16 +237,46 @@ class PlotWidget(BasePlotWidget):
TWC_time = 0.0
ideal_time = 0.0
worst_perf = 2
# TODO: рассчитать корректный параметр range
if settings["mirror ME"]:
dataframe = self._mirror_shift_data("ME", description["Real_signals"], dataframe, range_ME)
# Итерация по точкам
for cur_point, point_data in enumerate(points_pocket):
# point_data структура: [point_timeframe, ideal_data, point_events]
point_timeframe, ideal_data, point_events = point_data
point_timeframe, ideal_dat, point_events, useful_p_data = point_data
ideal_data = copy.deepcopy(ideal_dat)
# TODO: проверить корректность расчетов
if settings["force compensation FE"]:
force = useful_p_data["force"]
F_comp = - force/k_hardness
point_idxs = dataframe[(dataframe["time"] >= point_timeframe[0]) & (dataframe["time"] <= point_timeframe[1])].index
dataframe.loc[point_idxs] = self._shift_data("FE", description["Real_signals"], dataframe.loc[point_idxs], F_comp)
# Модифицируем данные для отображения гарфика
if settings["ideals"] and settings["mirror ME"]:
for stage in point_events.keys():
ideal_data[stage] = self._mirror_shift_data("ME", description["Ideal_signals"], ideal_data[stage], range_ME)
# Добавляем реальные стадии
if settings["stages"]:
self._add_stage_regions(plot_widget, point_events, dataframe_headers, 75)
# TODO: подобрать не вырвеглазные цвета, возможно ограничить зону
if settings["workpiece"]:
x1 = point_timeframe[0]
dx = point_timeframe[1] - x1
y1 = useful_p_data["L2"]*1000
dy = useful_p_data["thickness"]*1000
rect_item = QGraphicsRectItem(x1, y1, dx, dy)
rect_item.setBrush(pg.mkBrush('blue'))
rect_item.setPen(pg.mkPen('red', width=2))
plot_widget.addItem(rect_item)
# Добавляем идеальные стадии и идеальные сигналы
if settings["ideals"]:
self._add_ideal_stage_regions(plot_widget, ideal_data, point_events, 100)

View File

@ -25,6 +25,7 @@ def main():
controller.signal_widgets.connect(window.show_plot_tabs)
controller.signal_settings.connect(mediator.push_settings)
controller.signal_monitor.connect(monitor.custom_dir_extract)
window.push_settings()

View File

@ -111,7 +111,6 @@ class BasePlotWidget:
mediator: Optional[BaseMediator] = None):
super().__init__()
self._mediator = mediator
self._stage_colors = {
"Closing": [220, 20, 60, 100], # Crimson
@ -126,7 +125,10 @@ class BasePlotWidget:
"zoom": False,
"stages": True,
"performance": True,
"ideals": True
"ideals": True,
"mirror ME": False,
"workpiece": False,
"force compensation FE": False
},
"Real_signals": [
{
@ -154,7 +156,10 @@ class BasePlotWidget:
"zoom": False,
"stages": True,
"performance": False,
"ideals": True
"ideals": True,
"mirror ME": True,
"workpiece": True,
"force compensation FE": True
},
"Real_signals": [
{
@ -182,7 +187,10 @@ class BasePlotWidget:
"zoom": False,
"stages": True,
"performance": False,
"ideals": True
"ideals": True,
"mirror ME": False,
"workpiece": False,
"force compensation FE": False
},
"Real_signals": [
{
@ -246,6 +254,9 @@ class BaseController(QObject):
def push_settings(self, settings: list[dict]) -> None:
...
def open_custom_file (self, filepath: str) -> None:
...
class BaseIdealDataBuilder(OptAlgorithm):