diff --git a/.gitignore b/.gitignore index f12270b..45f8dfa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ /tck_venv /.venv /.idea -/venv \ No newline at end of file +/venv +*.txt +*.svg \ No newline at end of file diff --git a/UML.svg b/UML.svg deleted file mode 100644 index ce20333..0000000 --- a/UML.svg +++ /dev/null @@ -1 +0,0 @@ -Electrode Closing Algorithm DoneElectrode Closing Algorithm ExecuteSTEP 1: ME Move to S1STEP 1: ME Move to S1 CompleteSTEP 2: ME Move to P2STEP 2: ME Move to P2 CompleteSTEP 3: ME Hold P2STEP 3: ME Hold P2 AND Condition Start Force ControlSTEP 4: ME Force ControlReal dataclosurecompressionClient dataclosurecompressionopeningIdeal dataclosurecompressionopening05691106157164165166176191210220300 \ No newline at end of file diff --git a/UML.txt b/UML.txt deleted file mode 100644 index 3b74a7d..0000000 --- a/UML.txt +++ /dev/null @@ -1,76 +0,0 @@ -@startuml - -binary "Electrode Closing Algorithm Done" as bool_0<> -binary "Electrode Closing Algorithm Execute" as bool_1<> -binary "STEP 1: ME Move to S1" as bool_2<> -binary "STEP 1: ME Move to S1 Complete" as bool_3<> -binary "STEP 2: ME Move to P2" as bool_4<> -binary "STEP 2: ME Move to P2 Complete" as bool_5<> -binary "STEP 3: ME Hold P2" as bool_6<> -binary "STEP 3: ME Hold P2 AND Condition Start Force Control" as bool_7<> -binary "STEP 4: ME Force Control" as bool_8<> -concise "Real data" as RD -concise "Client data" as CD -concise "Ideal data" as ID -@0.0 -bool_0 is low -bool_1 is high -bool_2 is high -bool_3 is low -bool_4 is low -bool_5 is low -bool_6 is low -bool_7 is low -bool_8 is low -RD is closure #green -CD is closure -ID is closure #yellow -@191.0000090720132 -bool_0 is high -bool_1 is low -RD is {-} -@106.5000050584785 -bool_2 is low -bool_3 is low -bool_4 is high -@106.0000050347298 -bool_3 is high -@157.5000074808485 -bool_4 is low -bool_6 is high -@165.0000078370794 -bool_6 is low -bool_7 is low -bool_8 is high -RD is {-} -@164.5000078133307 -bool_7 is high -RD is compression #green -@165.0 -CD is {-} -@166.0 -CD is compression -@176.0 -CD is {-} -@210.0 -CD is opening -@300.0 -CD is {-} -@56.27781200794141 -ID is {-} -@56.37781200794141 -ID is compression #yellow -@91.4562305565861 -ID is {-} -@91.55623055658612 -ID is opening #yellow -@220.34565355083035 -ID is {-} -@enduml diff --git a/main.py b/main.py index fa7e05a..65e9bcb 100644 --- a/main.py +++ b/main.py @@ -1,23 +1,26 @@ import pyqtgraph as pg import numpy as np -from utils import read_json, DataParser -from Requestinator import Request +from utils import read_json, DiagramParser +from uml import Request, UMLCreator #нижний fe x1 import qt_settings as qts from OptAlgorithm import OptAlgorithm class Application: - def __init__(self, opt: OptAlgorithm): + def __init__(self, + opt: OptAlgorithm, + bool_dict: dict, + float_dict: dict): pg.setConfigOptions(antialias=True) self.opt = opt + self.bool_dict = bool_dict + self.float_dict = float_dict + self.scaler = 1000 - self.parser = DataParser(self.scaler) - self.r = Request() self._getIdealTimings() self._init_app() - self.updateUML() self.WeldTime = 0.5 #[sec] self.alpha = 100 #[0-255 прозрачность фона] @@ -55,103 +58,12 @@ class Application: legend1 = pg.LegendItem((80,60), offset=(70,20)) legend1.setParentItem(p11) return p11, legend1 - - def updateUML(self, path = '2024_10_28-17_03_34.csv'): - real, client, ideal, bool = self._form_UMLdata(path) - self._requestSVG(real, client, ideal, bool) def updatePlots(self): self._plotRealData() times = np.arange(20000)/10 self._plotIdealData(times) - def _requestSVG(self, real_data, client_data, ideal_data, bool_data): - try: - - self.r.clear() - self.r.addLineStyle('biba', 'red', 2) - for i, [signal, changes] in enumerate(bool_data.items()): - name = 'bool_'+str(i) - self.r.addBinary(name, str(signal), 'biba') - self.r.setTimestamps(name, changes) - - self.r.addConcise('RD', 'Real data') - self.r.setTimestamps('RD', real_data) - self.r.addConcise('CD', 'Client data') - self.r.setTimestamps('CD', client_data) - self.r.addConcise('ID', 'Ideal data') - self.r.setTimestamps('ID', ideal_data) - - self.r.generateSVG() - except Exception as e: - print ('Ну, svg у нас нет') - - - def _form_UMLdata(self, path): - scaler = self.scaler - sig = [ - 'Electrode Closing Algorithm Execute', #Начало закрытия - 'Electrode Closing Algorithm Done', - 'STEP 3: ME Hold P2 AND Condition Start Force Control', #Конец закрытия и Начало набора усилия - 'STEP 4: ME Force Control', - 'Position Control ME', #Начало разъезда или 'Posision Control Activated FE' - 'Position Control FE', #Начало разъезда - 'Position Control Completed ME', #Конец разъезда - 'Position Control Completed FE', #Конец разъезда - 'STEP 4: ME Force Control Complete', #Конец набора усилия - ] - - self.parser.setData(path) - self.bool_dict = self.parser.getBoolDict() - self.float_dict = self.parser.getFloatDict() - - closure = self.__getTime([sig[0], sig[1]]) - compression = self.__getTime([sig[2], sig[3]]) - #opening = self.__getTime([sig[4], sig[5], sig[6], sig[7]]) - - real_data = [ - [closure[0], 'closure #green'], - [closure[1], '{-}'], - [compression[0], 'compression #green'], - [compression[1], '{-}'], - #[max(opening[0:2]), 'opening #green'], - #[max(opening[2:4]), '{-}'], - ] - - client_data = [ - [0.0*scaler, 'closure'], - [0.165*scaler, '{-}'], - [0.166*scaler, 'compression'], - [0.176*scaler, '{-}'], - #[0.180*scaler, 'welding'], - #[0.200*scaler, '{-}'], - [0.210*scaler, 'opening'], - [0.300*scaler, '{-}'], - ] - - ideal_data = [ - [0.0*scaler, 'closure #yellow'], - [self.idealTime[0]*scaler, '{-}'], - [(self.idealTime[0] + 0.0001)*scaler, 'compression #yellow'], - [(self.idealTime[0] + self.idealTime[1])*scaler, '{-}'], - #[0.*scaler, 'welding #yellow'], - #[0.*scaler, '{-}'], - [(self.idealTime[0] + self.idealTime[1] + 0.0001)*scaler, 'opening #yellow'], - [(self.idealTime[0] + self.idealTime[1] + self.idealTime[2])*scaler, '{-}'], - ] - return real_data, client_data, ideal_data, self.bool_dict - - def __getTime(self, signals = '', states = ''): - res = [] - for i, sig in enumerate(signals): - if states: state = states[i] - else: state = 'high' - index1 = next ((i for i, _ in enumerate(self.bool_dict[sig]) if _[1]==state), -1) - time = self.bool_dict[sig][index1][0] - res.append(time) - return res - - def _getIdealTimings(self): data = self.opt.Ts self.idealTime = [data['tclose'], data['tgrow'], self.opt.getMarkOpen()] @@ -239,16 +151,37 @@ class Application: self.p13.setYRange(-400, 400) +def get_ideal_timings(opt: OptAlgorithm) -> list[float]: + data = opt.Ts + ideal_time = [data['tclose'], data['tgrow'], opt.getMarkOpen()] + return ideal_time - - - -if __name__ == '__main__': +def main(): operator_params = read_json("params/operator_params.json") system_params = read_json("params/system_params.json") opt_algorithm = OptAlgorithm(operator_config=operator_params, system_config=system_params) - app = Application(opt_algorithm) + ideal_times = get_ideal_timings(opt_algorithm) + + parser = DiagramParser() + parser.setData("2024_10_28-17_03_34.csv") + bool_dict = parser.getBoolDict() + float_dict = parser.getFloatDict() + + request_generator = Request(server_url='http://www.plantuml.com/plantuml/svg/') + uml_creator = UMLCreator(request_generator=request_generator, + ideal_time=ideal_times, + bool_dict=bool_dict, + float_dict=float_dict) + uml_creator.update_uml() + + app = Application(opt=opt_algorithm, + bool_dict=bool_dict, + float_dict=float_dict) + app.updatePlots() pg.exec() + +if __name__ == '__main__': + main() diff --git a/uml/__init__.py b/uml/__init__.py new file mode 100644 index 0000000..a275da1 --- /dev/null +++ b/uml/__init__.py @@ -0,0 +1,2 @@ +from .request_generator import Request +from .creator import UMLCreator \ No newline at end of file diff --git a/uml/creator.py b/uml/creator.py new file mode 100644 index 0000000..2a61845 --- /dev/null +++ b/uml/creator.py @@ -0,0 +1,99 @@ +import os +from uml.request_generator import Request + + +class UMLCreator: + def __init__(self, + request_generator: Request, + ideal_time: list[float], + bool_dict: dict, + float_dict: dict): + self._request_generator = request_generator + self._ideal_time = ideal_time + self.bool_dict = bool_dict + self.float_dict = float_dict + + def _build_data(self): + scaler = 1000 # TODO: external config? + sig = [ + 'Electrode Closing Algorithm Execute', # Начало закрытия + 'Electrode Closing Algorithm Done', + 'STEP 3: ME Hold P2 AND Condition Start Force Control', # Конец закрытия и Начало набора усилия + 'STEP 4: ME Force Control', + 'Position Control ME', # Начало разъезда или 'Posision Control Activated FE' + 'Position Control FE', # Начало разъезда + 'Position Control Completed ME', # Конец разъезда + 'Position Control Completed FE', # Конец разъезда + 'STEP 4: ME Force Control Complete', # Конец набора усилия + ] + closure = self._get_time([sig[0], sig[1]]) + compression = self._get_time([sig[2], sig[3]]) + # opening = self.__getTime([sig[4], sig[5], sig[6], sig[7]]) + + real_data = [ + [closure[0], 'closure #green'], + [closure[1], '{-}'], + [compression[0], 'compression #green'], + [compression[1], '{-}'], + # [max(opening[0:2]), 'opening #green'], + # [max(opening[2:4]), '{-}'], + ] + + client_data = [ + [0.0 * scaler, 'closure'], + [0.165 * scaler, '{-}'], + [0.166 * scaler, 'compression'], + [0.176 * scaler, '{-}'], + # [0.180*scaler, 'welding'], + # [0.200*scaler, '{-}'], + [0.210 * scaler, 'opening'], + [0.300 * scaler, '{-}'], + ] + + ideal_data = [ + [0.0 * scaler, 'closure #yellow'], + [self._ideal_time[0] * scaler, '{-}'], + [(self._ideal_time[0] + 0.0001) * scaler, 'compression #yellow'], + [(self._ideal_time[0] + self._ideal_time[1]) * scaler, '{-}'], + # [0.*scaler, 'welding #yellow'], + # [0.*scaler, '{-}'], + [(self._ideal_time[0] + self._ideal_time[1] + 0.0001) * scaler, 'opening #yellow'], + [(self._ideal_time[0] + self._ideal_time[1] + self._ideal_time[2]) * scaler, '{-}'], + ] + return real_data, client_data, ideal_data, self.bool_dict + + def _get_time(self, signals = '', states = ''): + res = [] + for i, sig in enumerate(signals): + if states: state = states[i] + else: state = 'high' + index1 = next ((i for i, _ in enumerate(self.bool_dict[sig]) if _[1]==state), -1) + time = self.bool_dict[sig][index1][0] + res.append(time) + return res + + def _generate_svg(self, real_data, client_data, ideal_data, bool_data) -> None: + try: + self._request_generator.clear() + self._request_generator.addLineStyle('biba', 'red', 2) + + for i, [signal, changes] in enumerate(bool_data.items()): + name = 'bool_' + str(i) + self._request_generator.addBinary(name, str(signal), 'biba') + self._request_generator.setTimestamps(name, changes) + + self._request_generator.addConcise('RD', 'Real data') + self._request_generator.setTimestamps('RD', real_data) + self._request_generator.addConcise('CD', 'Client data') + self._request_generator.setTimestamps('CD', client_data) + self._request_generator.addConcise('ID', 'Ideal data') + self._request_generator.setTimestamps('ID', ideal_data) + + self._request_generator.generateSVG() + + except Exception as e: + print(f"SVG generate error: {e}") + + def update_uml(self) -> None: + real, client, ideal, bool_ = self._build_data() + self._generate_svg(real, client, ideal, bool_) diff --git a/Requestinator.py b/uml/request_generator.py similarity index 92% rename from Requestinator.py rename to uml/request_generator.py index cfeef9c..4dbf109 100644 --- a/Requestinator.py +++ b/uml/request_generator.py @@ -3,8 +3,13 @@ from os.path import abspath class Request: - def __init__(self): - self.server = PlantUML(url='http://www.plantuml.com/plantuml/svg/') + def __init__(self, server_url: str): + self._server_url = server_url + + self._init_server() + + def _init_server(self): + self.server = PlantUML(url=self._server_url) self.clear() def _startUML(self): @@ -45,7 +50,7 @@ class Request: def generateSVG(self): self._compileUML() - filename = abspath('UML.txt') + filename = abspath('../UML.txt') self.server.processes_file(filename, outfile='UML.svg') #result = self.server.processes(self.stringUML) #return result diff --git a/utils/__init__.py b/utils/__init__.py index 5ed4f0d..5cedfcd 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -1,2 +1,2 @@ from .json_tools import read_json -from .data_parser import DataParser +from .diagram_parser import DiagramParser \ No newline at end of file diff --git a/utils/data_parser.py b/utils/diagram_parser.py similarity index 98% rename from utils/data_parser.py rename to utils/diagram_parser.py index a363801..36110c7 100644 --- a/utils/data_parser.py +++ b/utils/diagram_parser.py @@ -1,7 +1,7 @@ import pandas as pd import numpy as np -class DataParser: +class DiagramParser: def __init__(self, scaler = 1): self.data = pd.DataFrame({}) self.scaler = scaler