dev: добавлено построение идеального графика
This commit is contained in:
parent
bf155af58a
commit
d99fafd2ae
@ -192,7 +192,7 @@
|
|||||||
0.0045
|
0.0045
|
||||||
],
|
],
|
||||||
"force_target": [
|
"force_target": [
|
||||||
4000.0,
|
5000.0,
|
||||||
5000.0,
|
5000.0,
|
||||||
5000.0,
|
5000.0,
|
||||||
5000.0,
|
5000.0,
|
||||||
|
|||||||
Binary file not shown.
BIN
src - Ярлык.lnk
BIN
src - Ярлык.lnk
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
#FIXME: костыль для выключения предупреждения "replace deprecated". Потом надо поправить.
|
# FIXME: костыль для выключения предупреждения "replace deprecated"
|
||||||
pd.set_option('future.no_silent_downcasting', True)
|
pd.set_option('future.no_silent_downcasting', True)
|
||||||
|
|
||||||
from utils.base.base import BaseDataConverter
|
from utils.base.base import BaseDataConverter
|
||||||
@ -15,6 +15,9 @@ class DataConverter(BaseDataConverter):
|
|||||||
return dataframe
|
return dataframe
|
||||||
|
|
||||||
def convert_data(self, files: list[str]) -> None:
|
def convert_data(self, files: list[str]) -> None:
|
||||||
dataframes = [pd.read_csv(file) for file in files]
|
try:
|
||||||
converted_dataframes = list(map(self._replace_bool, dataframes))
|
dataframes = [pd.read_csv(file) for file in files]
|
||||||
self._mediator.notify(self, converted_dataframes)
|
converted_dataframes = list(map(self._replace_bool, dataframes))
|
||||||
|
self._mediator.notify(self, converted_dataframes)
|
||||||
|
except:
|
||||||
|
self._mediator.notify(self, [None])
|
||||||
|
|||||||
@ -58,6 +58,9 @@ class DirectoryMonitor(BaseDirectoryMonitor):
|
|||||||
self._files = [path]
|
self._files = [path]
|
||||||
if path is not None:
|
if path is not None:
|
||||||
self._mediator.notify(self, [path])
|
self._mediator.notify(self, [path])
|
||||||
|
else:
|
||||||
|
self._mediator.notify(self, [None])
|
||||||
|
|
||||||
|
|
||||||
def start_seeking(self) -> None:
|
def start_seeking(self) -> None:
|
||||||
self._init_state()
|
self._init_state()
|
||||||
|
|||||||
@ -25,7 +25,7 @@ class idealDataBuilder(BaseIdealDataBuilder):
|
|||||||
|
|
||||||
def get_ideal_timings(self) -> list[float]:
|
def get_ideal_timings(self) -> list[float]:
|
||||||
data = self.Ts
|
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
|
return ideal_timings
|
||||||
|
|
||||||
class PassportFormer(BasePointPassportFormer):
|
class PassportFormer(BasePointPassportFormer):
|
||||||
@ -36,49 +36,50 @@ class PassportFormer(BasePointPassportFormer):
|
|||||||
|
|
||||||
|
|
||||||
def _build_passports_pocket(self, dataframe: pd.DataFrame) -> list[pd.DataFrame, dict, int]:
|
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", []))
|
tesla_time = sum(self._params[0].get("Tesla summary time", []))
|
||||||
useful_data = {"tesla_time": tesla_time,
|
useful_data = {"tesla_time": tesla_time,
|
||||||
"range_ME": system_settings["Range ME, mm"],
|
"range_ME": system_settings["Range ME, mm"],
|
||||||
"k_hardness": system_settings["k_hardness_1"]
|
"k_hardness": system_settings["k_hardness_1"]
|
||||||
}
|
}
|
||||||
|
|
||||||
points_pocket = []
|
for i in range(point_quantity):
|
||||||
|
operator_settings = {
|
||||||
time_is_valid = not dataframe["time"].isna().all()
|
key: (value[i] if i < len(value) else value[0])
|
||||||
|
for key, value in self._params[0].items()
|
||||||
if time_is_valid:
|
}
|
||||||
|
params_list = [operator_settings, system_settings]
|
||||||
idx_shift = True if events[self._stages[-1]][0][0] == 0 else False
|
cache_key = self._generate_cache_key(params_list)
|
||||||
|
if cache_key in self._ideal_data_cashe :
|
||||||
for i in range(point_quantity):
|
ideal_data = self._ideal_data_cashe[cache_key]
|
||||||
operator_settings = {
|
print(f"Cache hit")
|
||||||
key: (value[i] if i < len(value) else value[0])
|
else:
|
||||||
for key, value in self._params[0].items()
|
ideal_data = self._build_ideal_data(idealDataBuilder=idealDataBuilder, params=params_list)
|
||||||
}
|
self._ideal_data_cashe[cache_key] = ideal_data
|
||||||
params_list = [operator_settings, system_settings]
|
print(f"Cache miss. Computed and cached.")
|
||||||
cache_key = self._generate_cache_key(params_list)
|
if events is not None:
|
||||||
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.")
|
|
||||||
idx = i+1 if idx_shift else i
|
idx = i+1 if idx_shift else i
|
||||||
point_timeframe = [events[self._stages[0]][0][i], events[self._stages[-1]][1][idx]]
|
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()}
|
point_events = {key: [value[0][i], value[1][i]] for key, value in events.items()}
|
||||||
useful_p_data = {"thickness": operator_settings["object_thickness"],
|
else:
|
||||||
"L2": operator_settings["distance_l_2"],
|
point_timeframe, point_events = None, None
|
||||||
"force": operator_settings["force_target"]}
|
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])
|
points_pocket.append([point_timeframe, ideal_data, point_events, useful_p_data])
|
||||||
return dataframe, points_pocket, useful_data
|
return dataframe, points_pocket, useful_data
|
||||||
|
|
||||||
def update_settings(self, params: list[dict, dict]):
|
def update_settings(self, params: list[dict, dict]):
|
||||||
self._params = params
|
self._params = params
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -93,15 +93,13 @@ class MainWindow(BaseMainWindow):
|
|||||||
self._clear()
|
self._clear()
|
||||||
self._transfer_settings()
|
self._transfer_settings()
|
||||||
path = self._select_csv()
|
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 = QtWidgets.QTabWidget()
|
||||||
self.tabWidget.setTabsClosable(True)
|
self.tabWidget.setTabsClosable(True)
|
||||||
self.tabWidget.tabCloseRequested.connect(self._close_tab)
|
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 = QtWidgets.QPushButton("System settings")
|
||||||
sys_settings_btn.setFixedWidth(185)
|
sys_settings_btn.setFixedWidth(185)
|
||||||
sys_settings_btn.clicked.connect(lambda: self.sysSettings.show())
|
sys_settings_btn.clicked.connect(lambda: self.sysSettings.show())
|
||||||
@ -131,6 +129,9 @@ class MainWindow(BaseMainWindow):
|
|||||||
mainLayout.addWidget(title, alignment=Qt.AlignRight)
|
mainLayout.addWidget(title, alignment=Qt.AlignRight)
|
||||||
self.resize(800,800)
|
self.resize(800,800)
|
||||||
self._controller.raport_mode(path)
|
self._controller.raport_mode(path)
|
||||||
|
self._controller.raport_mode(None)
|
||||||
|
|
||||||
|
#self._controller.raport_mode(path)
|
||||||
# TODO: push only one dir to monitor
|
# TODO: push only one dir to monitor
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -113,7 +113,7 @@ class PlotWidget(BasePlotWidget):
|
|||||||
point_events[stage][1]
|
point_events[stage][1]
|
||||||
)
|
)
|
||||||
if curve:
|
if curve:
|
||||||
curve.setZValue(10)
|
curve.setZValue(50)
|
||||||
plot_item.addItem(curve)
|
plot_item.addItem(curve)
|
||||||
curve_items["ideal"].setdefault(signal["name"], {})
|
curve_items["ideal"].setdefault(signal["name"], {})
|
||||||
curve_items["ideal"][signal["name"]].setdefault(stage, [])
|
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
|
TWC_ideal = round((ideal_time/TWC_time)*100, 2) if TWC_time else 0.0
|
||||||
|
|
||||||
performance_label = QLabel(
|
performance_label = QLabel(
|
||||||
f"Сокращение длительности: фактическое = {tesla_TWC} %, "
|
f"Сокращение длительности: фактическое = {tesla_TWC} %"
|
||||||
)
|
)
|
||||||
#f"идеальное = {tesla_ideal} %; КДИП = {TWC_ideal}%"
|
#f"идеальное = {tesla_ideal} %; КДИП = {TWC_ideal}%"
|
||||||
self.set_style(performance_label)
|
self.set_style(performance_label)
|
||||||
@ -172,7 +172,10 @@ class PlotWidget(BasePlotWidget):
|
|||||||
tesla_time = useful_data["tesla_time"]
|
tesla_time = useful_data["tesla_time"]
|
||||||
range_ME = useful_data["range_ME"]
|
range_ME = useful_data["range_ME"]
|
||||||
k_hardness = useful_data["k_hardness"]
|
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()):
|
for widget_num, (channel, description) in enumerate(self._plt_channels.items()):
|
||||||
plot_item, legend = self._init_plot_item(title=channel)
|
plot_item, legend = self._init_plot_item(title=channel)
|
||||||
@ -183,7 +186,7 @@ class PlotWidget(BasePlotWidget):
|
|||||||
worst_perf = 2
|
worst_perf = 2
|
||||||
|
|
||||||
# TODO: рассчитать корректный параметр range
|
# TODO: рассчитать корректный параметр range
|
||||||
if settings["mirror ME"]:
|
if settings["mirror ME"] and not dat_is_none:
|
||||||
dataframe = self._mirror_shift_data(
|
dataframe = self._mirror_shift_data(
|
||||||
"ME",
|
"ME",
|
||||||
description["Real_signals"],
|
description["Real_signals"],
|
||||||
@ -196,9 +199,18 @@ class PlotWidget(BasePlotWidget):
|
|||||||
# point_data структура: [point_timeframe, ideal_data, point_events, useful_p_data]
|
# point_data структура: [point_timeframe, ideal_data, point_events, useful_p_data]
|
||||||
point_timeframe, ideal_dat, point_events, useful_p_data = point_data
|
point_timeframe, ideal_dat, point_events, useful_p_data = point_data
|
||||||
ideal_data = copy.deepcopy(ideal_dat)
|
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: проверить корректность расчетов
|
# TODO: проверить корректность расчетов
|
||||||
if settings["force compensation FE"]:
|
if settings["force compensation FE"] and not dat_is_none:
|
||||||
force = useful_p_data["force"]
|
force = useful_p_data["force"]
|
||||||
F_comp = - force/k_hardness
|
F_comp = - force/k_hardness
|
||||||
point_idxs = dataframe[(dataframe["time"] >= point_timeframe[0]) & (dataframe["time"] <= point_timeframe[1])].index
|
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)
|
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)
|
self._add_stage_regions(plot_item, point_events, dataframe_headers, reg_items, 75)
|
||||||
|
|
||||||
if settings["workpiece"]:
|
if settings["workpiece"]:
|
||||||
@ -226,7 +238,7 @@ class PlotWidget(BasePlotWidget):
|
|||||||
rect_item.setPen(pg.mkPen('black', width=3))
|
rect_item.setPen(pg.mkPen('black', width=3))
|
||||||
plot_item.addItem(rect_item)
|
plot_item.addItem(rect_item)
|
||||||
|
|
||||||
if settings["force accuracy"]:
|
if settings["force accuracy"]and not dat_is_none:
|
||||||
modifier = 0.05
|
modifier = 0.05
|
||||||
|
|
||||||
x1 = point_events["Welding"][0]
|
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)
|
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)
|
is_last_point = (cur_point == len(points_pocket) - 1)
|
||||||
if is_last_point:
|
if is_last_point:
|
||||||
TWC_delta = sum([point_events[stage][1] - point_events[stage][0] for stage in ["Closing", "Squeeze", "Welding"]])
|
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
|
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:
|
if widget_num == 0:
|
||||||
main_plot = plot_item
|
main_plot = plot_item
|
||||||
else:
|
else:
|
||||||
# Связываем остальные графики с основным графиком
|
# Связываем остальные графики с основным графиком
|
||||||
plot_item.setXLink(main_plot)
|
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)
|
self._add_performance_label(result_layout, TWC_time, ideal_time, tesla_time)
|
||||||
|
|
||||||
plot_layout.addItem(plot_item, widget_num, 0)
|
plot_layout.addItem(plot_item, widget_num, 0)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -128,7 +128,7 @@ class BasePlotWidget:
|
|||||||
"zoom": False,
|
"zoom": False,
|
||||||
"stages": True,
|
"stages": True,
|
||||||
"performance": True,
|
"performance": True,
|
||||||
"ideals": False,
|
"ideals": True,
|
||||||
"mirror ME": False,
|
"mirror ME": False,
|
||||||
"workpiece": False,
|
"workpiece": False,
|
||||||
"force compensation FE": False,
|
"force compensation FE": False,
|
||||||
@ -160,7 +160,7 @@ class BasePlotWidget:
|
|||||||
"zoom": False,
|
"zoom": False,
|
||||||
"stages": True,
|
"stages": True,
|
||||||
"performance": False,
|
"performance": False,
|
||||||
"ideals": False,
|
"ideals": True,
|
||||||
"mirror ME": True,
|
"mirror ME": True,
|
||||||
"workpiece": True,
|
"workpiece": True,
|
||||||
"force compensation FE": True,
|
"force compensation FE": True,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user