dev: добавлено построение идеального графика

This commit is contained in:
Andrew 2024-12-19 13:23:27 +03:00
parent bf155af58a
commit d99fafd2ae
27 changed files with 78 additions and 57 deletions

View File

@ -192,7 +192,7 @@
0.0045
],
"force_target": [
4000.0,
5000.0,
5000.0,
5000.0,
5000.0,

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,6 @@
import pandas as pd
#FIXME: костыль для выключения предупреждения "replace deprecated". Потом надо поправить.
# FIXME: костыль для выключения предупреждения "replace deprecated"
pd.set_option('future.no_silent_downcasting', True)
from utils.base.base import BaseDataConverter
@ -15,6 +15,9 @@ class DataConverter(BaseDataConverter):
return dataframe
def convert_data(self, files: list[str]) -> None:
dataframes = [pd.read_csv(file) for file in files]
converted_dataframes = list(map(self._replace_bool, dataframes))
self._mediator.notify(self, converted_dataframes)
try:
dataframes = [pd.read_csv(file) for file in files]
converted_dataframes = list(map(self._replace_bool, dataframes))
self._mediator.notify(self, converted_dataframes)
except:
self._mediator.notify(self, [None])

View File

@ -58,6 +58,9 @@ class DirectoryMonitor(BaseDirectoryMonitor):
self._files = [path]
if path is not None:
self._mediator.notify(self, [path])
else:
self._mediator.notify(self, [None])
def start_seeking(self) -> None:
self._init_state()

View File

@ -25,7 +25,7 @@ class idealDataBuilder(BaseIdealDataBuilder):
def get_ideal_timings(self) -> list[float]:
data = self.Ts
ideal_timings = [data['tclose'], data['tgrow'], self.welding_time, self.getMarkOpen(), data['tmovement']] # TODO: add data['tmovement'], Oncoming не учитывается в производительности
ideal_timings = [data['tclose'], data['tgrow'], self.welding_time, self.getMarkOpen(), data['tmovement']]
return ideal_timings
class PassportFormer(BasePointPassportFormer):
@ -36,49 +36,50 @@ class PassportFormer(BasePointPassportFormer):
def _build_passports_pocket(self, dataframe: pd.DataFrame) -> list[pd.DataFrame, dict, int]:
events, point_quantity = self._filter_events(dataframe["time"], dataframe)
if point_quantity == 0:
return []
system_settings = {key: value[0] for key, value in self._params[1].items()}
if dataframe is not None:
events, point_quantity = self._filter_events(dataframe["time"], dataframe)
if point_quantity == 0:
return []
idx_shift = True if events[self._stages[-1]][0][0] == 0 else False
else:
events = None
point_quantity = 1
points_pocket = []
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 = []
time_is_valid = not dataframe["time"].isna().all()
if time_is_valid:
idx_shift = True if events[self._stages[-1]][0][0] == 0 else False
for i in range(point_quantity):
operator_settings = {
key: (value[i] if i < len(value) else value[0])
for key, value in self._params[0].items()
}
params_list = [operator_settings, system_settings]
cache_key = self._generate_cache_key(params_list)
if cache_key in self._ideal_data_cashe :
ideal_data = self._ideal_data_cashe[cache_key]
print(f"Cache hit")
else:
ideal_data = self._build_ideal_data(idealDataBuilder=idealDataBuilder, params=params_list)
self._ideal_data_cashe[cache_key] = ideal_data
print(f"Cache miss. Computed and cached.")
for i in range(point_quantity):
operator_settings = {
key: (value[i] if i < len(value) else value[0])
for key, value in self._params[0].items()
}
params_list = [operator_settings, system_settings]
cache_key = self._generate_cache_key(params_list)
if cache_key in self._ideal_data_cashe :
ideal_data = self._ideal_data_cashe[cache_key]
print(f"Cache hit")
else:
ideal_data = self._build_ideal_data(idealDataBuilder=idealDataBuilder, params=params_list)
self._ideal_data_cashe[cache_key] = ideal_data
print(f"Cache miss. Computed and cached.")
if events is not None:
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"]}
else:
point_timeframe, point_events = None, None
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, useful_p_data])
return dataframe, points_pocket, useful_data
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

@ -93,15 +93,13 @@ class MainWindow(BaseMainWindow):
self._clear()
self._transfer_settings()
path = self._select_csv()
if path is None:
self.layout().addWidget(QtWidgets.QLabel("Error. Please select correct path to csv"))
self._init_startUI()
return
self._transfer_settings()
self.tabWidget = QtWidgets.QTabWidget()
self.tabWidget.setTabsClosable(True)
self.tabWidget.tabCloseRequested.connect(self._close_tab)
if path is None:
self.layout().addWidget(QtWidgets.QLabel("Error. Please select correct path to csv"))
self._init_startUI()
self._controller.raport_mode(None)
sys_settings_btn = QtWidgets.QPushButton("System settings")
sys_settings_btn.setFixedWidth(185)
sys_settings_btn.clicked.connect(lambda: self.sysSettings.show())
@ -131,6 +129,9 @@ class MainWindow(BaseMainWindow):
mainLayout.addWidget(title, alignment=Qt.AlignRight)
self.resize(800,800)
self._controller.raport_mode(path)
self._controller.raport_mode(None)
#self._controller.raport_mode(path)
# TODO: push only one dir to monitor

View File

@ -113,7 +113,7 @@ class PlotWidget(BasePlotWidget):
point_events[stage][1]
)
if curve:
curve.setZValue(10)
curve.setZValue(50)
plot_item.addItem(curve)
curve_items["ideal"].setdefault(signal["name"], {})
curve_items["ideal"][signal["name"]].setdefault(stage, [])
@ -150,7 +150,7 @@ class PlotWidget(BasePlotWidget):
TWC_ideal = round((ideal_time/TWC_time)*100, 2) if TWC_time else 0.0
performance_label = QLabel(
f"Сокращение длительности: фактическое = {tesla_TWC} %, "
f"Сокращение длительности: фактическое = {tesla_TWC} %"
)
#f"идеальное = {tesla_ideal} %; КДИП = {TWC_ideal}%"
self.set_style(performance_label)
@ -172,7 +172,10 @@ class PlotWidget(BasePlotWidget):
tesla_time = useful_data["tesla_time"]
range_ME = useful_data["range_ME"]
k_hardness = useful_data["k_hardness"]
dataframe_headers = dataframe.columns.tolist()
dat_is_none = dataframe is None
if not dat_is_none: dataframe_headers = dataframe.columns.tolist()
for widget_num, (channel, description) in enumerate(self._plt_channels.items()):
plot_item, legend = self._init_plot_item(title=channel)
@ -183,7 +186,7 @@ class PlotWidget(BasePlotWidget):
worst_perf = 2
# TODO: рассчитать корректный параметр range
if settings["mirror ME"]:
if settings["mirror ME"] and not dat_is_none:
dataframe = self._mirror_shift_data(
"ME",
description["Real_signals"],
@ -196,9 +199,18 @@ class PlotWidget(BasePlotWidget):
# point_data структура: [point_timeframe, ideal_data, point_events, useful_p_data]
point_timeframe, ideal_dat, point_events, useful_p_data = point_data
ideal_data = copy.deepcopy(ideal_dat)
if dat_is_none:
worst_timeframe = point_timeframe = [0, ideal_data["Ideal cycle"]]
point_events = {}
keys = list(ideal_data.keys())
shift = 0
for i, time in enumerate(ideal_data["Ideal timings"]):
point_events[keys[i]] = [shift, time+shift]
shift += time
# TODO: проверить корректность расчетов
if settings["force compensation FE"]:
if settings["force compensation FE"] and not dat_is_none:
force = useful_p_data["force"]
F_comp = - force/k_hardness
point_idxs = dataframe[(dataframe["time"] >= point_timeframe[0]) & (dataframe["time"] <= point_timeframe[1])].index
@ -211,7 +223,7 @@ class PlotWidget(BasePlotWidget):
ideal_data[stage] = self._mirror_shift_data("ME", description["Ideal_signals"], ideal_data[stage], range_ME)
# Добавляем реальные стадии
if settings["stages"]:
if settings["stages"] and not dat_is_none:
self._add_stage_regions(plot_item, point_events, dataframe_headers, reg_items, 75)
if settings["workpiece"]:
@ -226,7 +238,7 @@ class PlotWidget(BasePlotWidget):
rect_item.setPen(pg.mkPen('black', width=3))
plot_item.addItem(rect_item)
if settings["force accuracy"]:
if settings["force accuracy"]and not dat_is_none:
modifier = 0.05
x1 = point_events["Welding"][0]
@ -247,7 +259,7 @@ class PlotWidget(BasePlotWidget):
self._add_ideal_signals(plot_item, ideal_data, point_events, description["Ideal_signals"], curve_items)
# Подсчёт производительности
if settings["performance"]:
if settings["performance"]and not dat_is_none:
is_last_point = (cur_point == len(points_pocket) - 1)
if is_last_point:
TWC_delta = sum([point_events[stage][1] - point_events[stage][0] for stage in ["Closing", "Squeeze", "Welding"]])
@ -264,14 +276,15 @@ class PlotWidget(BasePlotWidget):
worst_timeframe = point_timeframe
# Добавляем реальные сигналы
self._add_real_signals(plot_item, dataframe, description["Real_signals"], legend, curve_items)
if not dat_is_none:
self._add_real_signals(plot_item, dataframe, description["Real_signals"], legend, curve_items)
if widget_num == 0:
main_plot = plot_item
else:
# Связываем остальные графики с основным графиком
plot_item.setXLink(main_plot)
if settings["performance"]:
if settings["performance"] and not dat_is_none:
self._add_performance_label(result_layout, TWC_time, ideal_time, tesla_time)
plot_layout.addItem(plot_item, widget_num, 0)

View File

@ -128,7 +128,7 @@ class BasePlotWidget:
"zoom": False,
"stages": True,
"performance": True,
"ideals": False,
"ideals": True,
"mirror ME": False,
"workpiece": False,
"force compensation FE": False,
@ -160,7 +160,7 @@ class BasePlotWidget:
"zoom": False,
"stages": True,
"performance": False,
"ideals": False,
"ideals": True,
"mirror ME": True,
"workpiece": True,
"force compensation FE": True,