Compare commits
3 Commits
8179a33964
...
bd3ca92171
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd3ca92171 | ||
|
|
fdec6e8f6e | ||
|
|
a66495af52 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -51,7 +51,6 @@ class DirectoryMonitor(BaseDirectoryMonitor):
|
|||||||
|
|
||||||
def update_plots(self):
|
def update_plots(self):
|
||||||
if self._files is not None:
|
if self._files is not None:
|
||||||
print("updPlot")
|
|
||||||
self._mediator.notify(self, self._files)
|
self._mediator.notify(self, self._files)
|
||||||
|
|
||||||
def custom_csv_extract_only(self, path: str):
|
def custom_csv_extract_only(self, path: str):
|
||||||
@ -62,15 +61,12 @@ class DirectoryMonitor(BaseDirectoryMonitor):
|
|||||||
self._mediator.notify(self, [None])
|
self._mediator.notify(self, [None])
|
||||||
|
|
||||||
def start_raport(self) -> None:
|
def start_raport(self) -> None:
|
||||||
print("startRaport")
|
|
||||||
self.stop()
|
self.stop()
|
||||||
self._files = []
|
self._files = ['']
|
||||||
print(self._files)
|
|
||||||
self._mediator.notify(self, [None])
|
self._mediator.notify(self, [None])
|
||||||
|
|
||||||
|
|
||||||
def start_seeking(self) -> None:
|
def start_seeking(self) -> None:
|
||||||
print("startSeeking")
|
|
||||||
self._init_state()
|
self._init_state()
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
import traceback
|
||||||
|
import sys
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
from utils.base.base import BasePointPassportFormer, BaseIdealDataBuilder
|
from utils.base.base import BasePointPassportFormer, BaseIdealDataBuilder
|
||||||
|
|
||||||
@ -32,8 +35,16 @@ class idealDataBuilder(BaseIdealDataBuilder):
|
|||||||
class PassportFormer(BasePointPassportFormer):
|
class PassportFormer(BasePointPassportFormer):
|
||||||
|
|
||||||
def form_passports(self, data: list[pd.DataFrame]) -> list[list[pd.DataFrame, dict, int]]:
|
def form_passports(self, data: list[pd.DataFrame]) -> list[list[pd.DataFrame, dict, int]]:
|
||||||
return_data = [self._build_passports_pocket(dataframe) for dataframe in data]
|
try:
|
||||||
self._mediator.notify(self, return_data)
|
return_data = [self._build_passports_pocket(dataframe) for dataframe in data]
|
||||||
|
except:
|
||||||
|
tb = sys.exc_info()[2]
|
||||||
|
tbinfo = traceback.format_tb(tb)[0]
|
||||||
|
pymsg = "Traceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
|
||||||
|
logger.error(pymsg)
|
||||||
|
return_data = []
|
||||||
|
finally:
|
||||||
|
self._mediator.notify(self, return_data)
|
||||||
|
|
||||||
|
|
||||||
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]:
|
||||||
@ -64,11 +75,9 @@ class PassportFormer(BasePointPassportFormer):
|
|||||||
cache_key = self._generate_cache_key(params_list)
|
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]
|
ideal_data = self._ideal_data_cashe[cache_key]
|
||||||
print(f"Cache hit")
|
|
||||||
else:
|
else:
|
||||||
ideal_data = self._build_ideal_data(idealDataBuilder=idealDataBuilder, params=params_list)
|
ideal_data = self._build_ideal_data(idealDataBuilder=idealDataBuilder, params=params_list)
|
||||||
self._ideal_data_cashe[cache_key] = ideal_data
|
self._ideal_data_cashe[cache_key] = ideal_data
|
||||||
print(f"Cache miss. Computed and cached.")
|
|
||||||
if events is not None:
|
if events is not None:
|
||||||
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]]
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -30,6 +30,7 @@ class MainWindow(BaseMainWindow):
|
|||||||
self.operSettings = OperatorSettings("params/operator_params.json", 'Operator', self._upd_settings)
|
self.operSettings = OperatorSettings("params/operator_params.json", 'Operator', self._upd_settings)
|
||||||
self.sysSettings = SystemSettings("params/system_params.json", 'System', self._upd_settings)
|
self.sysSettings = SystemSettings("params/system_params.json", 'System', self._upd_settings)
|
||||||
self.repSettings = ReportSettings()
|
self.repSettings = ReportSettings()
|
||||||
|
self.statusBar().showMessage("Ready")
|
||||||
|
|
||||||
self._clear()
|
self._clear()
|
||||||
self.resize(800,800)
|
self.resize(800,800)
|
||||||
@ -120,6 +121,7 @@ class MainWindow(BaseMainWindow):
|
|||||||
view_settings = QtWidgets.QAction("View settings", self)
|
view_settings = QtWidgets.QAction("View settings", self)
|
||||||
view_settings.setIcon(QIcon('resources/view_ico.png'))
|
view_settings.setIcon(QIcon('resources/view_ico.png'))
|
||||||
view_settings.triggered.connect(lambda: self._toggle_visibility(self.report_dock))
|
view_settings.triggered.connect(lambda: self._toggle_visibility(self.report_dock))
|
||||||
|
view_settings.triggered.connect(lambda: self._on_tab_changed(0))
|
||||||
|
|
||||||
|
|
||||||
# Добавляем действия в меню "Режимы"
|
# Добавляем действия в меню "Режимы"
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QGraphicsRectItem
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QGraphicsRectItem
|
||||||
import copy
|
import copy
|
||||||
|
import traceback
|
||||||
|
import sys
|
||||||
|
from loguru import logger
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from typing import Optional, Any
|
from typing import Optional, Any
|
||||||
@ -308,8 +311,16 @@ class PlotWidget(BasePlotWidget):
|
|||||||
...
|
...
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
widgets_datapack = [self._build_widget(data_sample) for data_sample in data]
|
try:
|
||||||
self._mediator.notify(self, widgets_datapack)
|
widgets_datapack = [self._build_widget(data_sample) for data_sample in data]
|
||||||
|
except:
|
||||||
|
tb = sys.exc_info()[2]
|
||||||
|
tbinfo = traceback.format_tb(tb)[0]
|
||||||
|
pymsg = "Traceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
|
||||||
|
logger.error(pymsg)
|
||||||
|
widgets_datapack = [QLabel(pymsg)]
|
||||||
|
finally:
|
||||||
|
self._mediator.notify(self, widgets_datapack)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2,7 +2,10 @@ import pyqtgraph as pg
|
|||||||
from pyqtgraph.parametertree import Parameter, ParameterTree
|
from pyqtgraph.parametertree import Parameter, ParameterTree
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from PyQt5 import QtWidgets
|
from PyQt5 import QtWidgets
|
||||||
from cachetools import LRUCache
|
import traceback
|
||||||
|
import sys
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ReportSettings(QtWidgets.QWidget):
|
class ReportSettings(QtWidgets.QWidget):
|
||||||
@ -12,28 +15,34 @@ class ReportSettings(QtWidgets.QWidget):
|
|||||||
|
|
||||||
def build(self, index, reg_items: dict, curve_items: dict) -> None:
|
def build(self, index, reg_items: dict, curve_items: dict) -> None:
|
||||||
"""Создает ParameterTree для элементов всех графиков выбранной вкладки"""
|
"""Создает ParameterTree для элементов всех графиков выбранной вкладки"""
|
||||||
self._clear()
|
try:
|
||||||
param_tree = ParameterTree()
|
self._clear()
|
||||||
layout = self.layout()
|
param_tree = ParameterTree()
|
||||||
layout.addWidget(param_tree)
|
layout = self.layout()
|
||||||
"""if index in self._tab_cashe:
|
layout.addWidget(param_tree)
|
||||||
body = self._tab_cashe[index]
|
"""if index in self._tab_cashe:
|
||||||
else:
|
body = self._tab_cashe[index]
|
||||||
|
else:
|
||||||
|
body= [
|
||||||
|
self._generate_reg_params(reg_items),
|
||||||
|
self._generate_curve_params(curve_items)
|
||||||
|
]
|
||||||
|
self._tab_cashe[index] = body"""
|
||||||
body= [
|
body= [
|
||||||
self._generate_reg_params(reg_items),
|
self._generate_reg_params(reg_items),
|
||||||
self._generate_curve_params(curve_items)
|
self._generate_curve_params(curve_items)
|
||||||
]
|
]
|
||||||
self._tab_cashe[index] = body"""
|
# Добавляем параметры в дерево
|
||||||
body= [
|
params = Parameter.create(name='params', type='group', children=body)
|
||||||
self._generate_reg_params(reg_items),
|
params.sigTreeStateChanged.connect(
|
||||||
self._generate_curve_params(curve_items)
|
lambda: self._update_settings(reg_items, curve_items, params)
|
||||||
]
|
)
|
||||||
# Добавляем параметры в дерево
|
param_tree.setParameters(params, showTop=False)
|
||||||
params = Parameter.create(name='params', type='group', children=body)
|
except:
|
||||||
params.sigTreeStateChanged.connect(
|
tb = sys.exc_info()[2]
|
||||||
lambda: self._update_settings(reg_items, curve_items, params)
|
tbinfo = traceback.format_tb(tb)[0]
|
||||||
)
|
pymsg = "Traceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
|
||||||
param_tree.setParameters(params, showTop=False)
|
logger.error(pymsg)
|
||||||
|
|
||||||
def _clear(self) -> None:
|
def _clear(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -2,14 +2,15 @@ from typing import Callable, Optional, Any
|
|||||||
from PyQt5.QtWidgets import (QWidget, QPushButton,
|
from PyQt5.QtWidgets import (QWidget, QPushButton,
|
||||||
QLineEdit, QHBoxLayout,
|
QLineEdit, QHBoxLayout,
|
||||||
QVBoxLayout, QLabel,
|
QVBoxLayout, QLabel,
|
||||||
QTableWidget, QTableWidgetItem)
|
QTableWidget, QTableWidgetItem,
|
||||||
from PyQt5.QtGui import QIntValidator
|
QStyledItemDelegate)
|
||||||
|
from PyQt5.QtGui import QIntValidator, QDoubleValidator
|
||||||
|
|
||||||
from utils.json_tools import read_json, write_json
|
from utils.json_tools import read_json, write_json
|
||||||
from utils import qt_settings as qts
|
from utils import qt_settings as qts
|
||||||
|
|
||||||
class settingsWindow(QWidget):
|
class settingsWindow(QWidget):
|
||||||
def __init__(self, path: str, name: str, upd_func: Callable[[], None]):
|
def __init__(self, path: str, name: str, upd_func: Callable[[], None], names: dict):
|
||||||
"""
|
"""
|
||||||
Окно настроек для редактирования параметров.
|
Окно настроек для редактирования параметров.
|
||||||
:param path: Путь к файлу настроек (JSON).
|
:param path: Путь к файлу настроек (JSON).
|
||||||
@ -24,6 +25,7 @@ class settingsWindow(QWidget):
|
|||||||
|
|
||||||
self._num_points: Optional[QLineEdit] = None
|
self._num_points: Optional[QLineEdit] = None
|
||||||
self._param_table: Optional[QTableWidget] = None
|
self._param_table: Optional[QTableWidget] = None
|
||||||
|
self._assosiated_names = names
|
||||||
|
|
||||||
self.load_settings()
|
self.load_settings()
|
||||||
self._init_ui()
|
self._init_ui()
|
||||||
@ -88,33 +90,35 @@ class settingsWindow(QWidget):
|
|||||||
self._param_table.setColumnCount(0)
|
self._param_table.setColumnCount(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
column_count = len(self._data[first_key]) + 1
|
column_count = len(self._data[first_key])
|
||||||
self._param_table.setRowCount(len(self._data))
|
self._param_table.setRowCount(len(self._data))
|
||||||
self._param_table.setColumnCount(column_count)
|
self._param_table.setColumnCount(column_count)
|
||||||
|
headers = [self._assosiated_names[key] for key in self._data.keys()]
|
||||||
|
self._param_table.setVerticalHeaderLabels(headers)
|
||||||
|
|
||||||
for i, (key, items) in enumerate(self._data.items()):
|
int_delegate = ValidatorDelegate(data_type='int', parent=self._param_table)
|
||||||
self._param_table.setItem(i, 0, QTableWidgetItem(key))
|
float_delegate = ValidatorDelegate(data_type='float', parent=self._param_table)
|
||||||
|
str_delegate = ValidatorDelegate(data_type='str', parent=self._param_table)
|
||||||
|
|
||||||
|
for i, (_, items) in enumerate(self._data.items()):
|
||||||
for j, item in enumerate(items):
|
for j, item in enumerate(items):
|
||||||
self._param_table.setItem(i, j+1, QTableWidgetItem(str(item)))
|
self._param_table.setItem(i, j, QTableWidgetItem(str(item)))
|
||||||
|
|
||||||
|
if type(item) == int:
|
||||||
|
self._param_table.setItemDelegateForRow(i, int_delegate)
|
||||||
|
elif type(item) == float:
|
||||||
|
self._param_table.setItemDelegateForRow(i, float_delegate)
|
||||||
|
else:
|
||||||
|
self._param_table.setItemDelegateForRow(i, str_delegate)
|
||||||
|
|
||||||
|
|
||||||
def _save(self) -> None:
|
def _save(self) -> None:
|
||||||
"""Сохраняет текущие параметры из таблицы в self._data и вызывает _upd_func()."""
|
"""Сохраняет текущие параметры из таблицы в self._data и вызывает _upd_func()."""
|
||||||
new_data = {}
|
new_data = {}
|
||||||
row_count = self._param_table.rowCount()
|
|
||||||
col_count = self._param_table.columnCount()
|
col_count = self._param_table.columnCount()
|
||||||
|
for i, key in enumerate(self._data.keys()):
|
||||||
for i in range(row_count):
|
|
||||||
key_item = self._param_table.item(i, 0)
|
|
||||||
if key_item is None:
|
|
||||||
continue
|
|
||||||
key = key_item.text()
|
|
||||||
|
|
||||||
# Если ключ пустой, пропускаем
|
|
||||||
if not key:
|
|
||||||
continue
|
|
||||||
|
|
||||||
row_data = []
|
row_data = []
|
||||||
for j in range(1, col_count):
|
for j in range(col_count):
|
||||||
cell_item = self._param_table.item(i, j)
|
cell_item = self._param_table.item(i, j)
|
||||||
if cell_item is None:
|
if cell_item is None:
|
||||||
continue
|
continue
|
||||||
@ -154,9 +158,9 @@ class settingsWindow(QWidget):
|
|||||||
return
|
return
|
||||||
|
|
||||||
prev_columns = self._param_table.columnCount()
|
prev_columns = self._param_table.columnCount()
|
||||||
desired_columns = num_points + 1
|
desired_columns = num_points
|
||||||
|
|
||||||
if desired_columns <= prev_columns:
|
if desired_columns <= 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
self._param_table.setColumnCount(desired_columns)
|
self._param_table.setColumnCount(desired_columns)
|
||||||
@ -178,16 +182,81 @@ class settingsWindow(QWidget):
|
|||||||
|
|
||||||
class SystemSettings(settingsWindow):
|
class SystemSettings(settingsWindow):
|
||||||
def __init__(self, path, name, upd_func):
|
def __init__(self, path, name, upd_func):
|
||||||
super().__init__(path, name, upd_func)
|
assosiated_names = {
|
||||||
|
"trace_storage_path": "trace path",
|
||||||
|
"monitor_update_period": "Monitoring period",
|
||||||
|
"a_max_1": "Max lin accel FE, m/s^2",
|
||||||
|
"v_max_1": "Max lin speed FE, m/s",
|
||||||
|
"a_max_2":"Max lin accel ME, m/s^2",
|
||||||
|
"v_max_2": "Max lin speed FE, m/s",
|
||||||
|
"mass_1": "Mass FE, kg",
|
||||||
|
"mass_2": "Mass ME, kg",
|
||||||
|
"k_hardness_1": "Hardness coef FE, N/m",
|
||||||
|
"k_hardness_2": "Hardness coef ME, N/m",
|
||||||
|
"torque_max_1": "Max torque FE, N*m",
|
||||||
|
"torque_max_2": "Max torque ME, N*m",
|
||||||
|
"transmission_ratio_1": "Transmission ratio FE",
|
||||||
|
"transmission_ratio_2": "Transmission ratio ME",
|
||||||
|
"contact_distance_1": "Contact distance FE, m",
|
||||||
|
"contact_distance_2": "Contact distance ME, m",
|
||||||
|
"k_prop": "Proportionality factor",
|
||||||
|
"time_capture": "Calculated points per sec",
|
||||||
|
"UML_time_scaler": "UML_time_scaler",
|
||||||
|
"Range ME, mm": "Range ME, mm"
|
||||||
|
}
|
||||||
|
super().__init__(path, name, upd_func, assosiated_names)
|
||||||
self._num_points.setVisible(False)
|
self._num_points.setVisible(False)
|
||||||
|
|
||||||
def _expand(self):
|
def _expand(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class OperatorSettings(settingsWindow):
|
class OperatorSettings(settingsWindow):
|
||||||
|
def __init__(self, path, name, upd_func):
|
||||||
|
assosiated_names = {
|
||||||
|
"distance_h_start_1": "Closing start dist FE, m" ,
|
||||||
|
"distance_h_start_2": "Closing start dist ME, m",
|
||||||
|
"distance_s_1": "Rob movement start dist FE, m",
|
||||||
|
"distance_s_2": "Rob movement start dist ME, m",
|
||||||
|
"distance_l_1": "Max oncoming dist FE, m",
|
||||||
|
"distance_l_2": "Max oncoming dist ME, m",
|
||||||
|
"distance_h_end1": "Oncoming end dist FE, m",
|
||||||
|
"distance_h_end2": "Oncoming end dist FE, m",
|
||||||
|
"time_wielding": "Time of welding, sec",
|
||||||
|
"time_command": "Communication time compensator, sec",
|
||||||
|
"time_robot_movement": "Rob movement time, sec",
|
||||||
|
"object_thickness": "Workpiece thickness, m",
|
||||||
|
"force_target": "Target force, N",
|
||||||
|
"force_capture": "Capture force, N",
|
||||||
|
"Tesla closing": "Client closing time, sec",
|
||||||
|
"Tesla squeeze": "Client squeeze time, sec",
|
||||||
|
"Tesla welding": "Client welding time, sec",
|
||||||
|
"Tesla oncomming_relief": "Client moving to next point time, sec",
|
||||||
|
"Tesla summary time": "Client summary time, sec"
|
||||||
|
}
|
||||||
|
super().__init__(path, name, upd_func, assosiated_names)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ValidatorDelegate(QStyledItemDelegate):
|
||||||
|
def __init__(self, data_type='str', parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.data_type = data_type
|
||||||
|
if self.data_type == 'int':
|
||||||
|
self.validator = QIntValidator()
|
||||||
|
elif self.data_type == 'float':
|
||||||
|
self.validator = QDoubleValidator()
|
||||||
|
self.validator.setNotation(QDoubleValidator.StandardNotation)
|
||||||
|
else:
|
||||||
|
self.validator = None
|
||||||
|
|
||||||
|
def createEditor(self, parent, option, index):
|
||||||
|
editor = QLineEdit(parent)
|
||||||
|
if self.validator:
|
||||||
|
editor.setValidator(self.validator)
|
||||||
|
return editor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
app = pg.mkQApp("Parameter Tree Example")
|
app = pg.mkQApp("Parameter Tree Example")
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user