From e1c38eeb2dfddfd1dedd4f6d765835ada794df89 Mon Sep 17 00:00:00 2001 From: ermolaev_p Date: Fri, 15 Nov 2024 14:34:31 +0300 Subject: [PATCH 01/13] =?UTF-8?q?fix(SF-483):=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BD=D0=B5=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D1=81=D1=87=D1=91=D1=82=20=D1=81=D0=BA=D0=BE=D1=80=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8=20=D0=BD=D0=B0=20=D1=8D=D1=82=D0=B0=D0=BF=D0=B5=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D1=8F,=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=B0=D1=81?= =?UTF-8?q?=D1=81=D0=B5=D1=80=D1=82=20=D0=BD=D0=B0=20=D0=B4=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=BE=D0=BC?= =?UTF-8?q?=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B9=20=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=B8=20=D0=B4=D0=BE?= =?UTF-8?q?=20=D1=84=D0=B0=D0=B7=D1=8B=20=D0=BF=D0=BE=D0=B4=D0=BF=D0=BE?= =?UTF-8?q?=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/OptAlgorithm/OptTimeCalculator.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/OptAlgorithm/OptTimeCalculator.py b/src/OptAlgorithm/OptTimeCalculator.py index aa1d9ce..17ca585 100644 --- a/src/OptAlgorithm/OptTimeCalculator.py +++ b/src/OptAlgorithm/OptTimeCalculator.py @@ -51,12 +51,10 @@ class OptTimeCalculator(AutoConfigClass): t22 = max(0, (l2 - (self.a_max_2 * t21 * t21)) / self.v_max_2) T2 = t22 + 2 * t21 + offset - Topen = max(T1, T2) - - topen_1_acc, topen_1_speed = self.calcFirstOpen(Topen, l1+Fs1) + topen_1_acc, topen_1_speed = self.calcFirstOpen(T1, l1+Fs1) offset = self.calcSecondOpenOffset(topen_1_acc, topen_1_speed, Fs1) - topen_2_acc, topen_2_speed = self.calcSecondOpen(Topen - offset, l2) + topen_2_acc, topen_2_speed = self.calcSecondOpen(T2 - offset, l2) self.allTimes["topen_1_acc"] = topen_1_acc self.allTimes["topen_2_offset"] = offset @@ -95,7 +93,6 @@ class OptTimeCalculator(AutoConfigClass): self.allTimes["topen_1_mark"] = topen_1_mark self.allTimes["topen_2_mark"] = topen_2_mark - self.allTimes["topen"] = Topen def Tgrow(self) -> None: @@ -109,7 +106,9 @@ class OptTimeCalculator(AutoConfigClass): tspeed = sqrt(self.mass_1/self.k_hardness_1) * (arcsin(vFmax / L) - arccos(sqrt(self.k_hardness_1 / self.mass_1) * self.eff_control / L)) Fspeed = - self.eff_control * cos(self.freq * tspeed) + self.eff_control + 1/self.freq * vF0 * sin(self.freq * tspeed) Fmeet = 1/self.freq * sqrt(self.freq**2 * self.Ftogrow**2 - vFmax**2) + Fstart_prop = self.Fstart_prop + assert Fmeet < Fstart_prop tmeet = (Fmeet - Fspeed)/vFmax tend = self.tGrowNominal(Fstart_prop) - self.tGrowNominal(Fmeet) vp = 1/sqrt(self.k_hardness_1 * self.mass_1) * sqrt(self.Ftogrow**2 - self.Fstart_prop**2) From 601f7912cfc4f4b739c69b882994c785e7173a0b Mon Sep 17 00:00:00 2001 From: ermolaev_p Date: Fri, 15 Nov 2024 15:57:31 +0300 Subject: [PATCH 02/13] =?UTF-8?q?fix(SF-483):=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=20=D0=BD=D0=B5=D1=80=D0=BF=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=D1=8C=D0=BD=D1=8B=D0=BC=20=D0=BD=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=D0=B0=D0=BC=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/OptAlgorithm/ConstantCalculator.py | 7 +++-- src/OptAlgorithm/OptTimeCalculator.py | 41 ++++++++++++++++---------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/OptAlgorithm/ConstantCalculator.py b/src/OptAlgorithm/ConstantCalculator.py index 7146fa2..24c5714 100644 --- a/src/OptAlgorithm/ConstantCalculator.py +++ b/src/OptAlgorithm/ConstantCalculator.py @@ -8,13 +8,14 @@ class ConstantCalculator(AutoConfigClass): super().__init__(ConstantCalculator.params_list, operator_config, system_config) + for param, value in self.__dict__.items(): + if value is int and value < 0: + raise Exception("""Недопустимое значение параметра {param} < 0""") + def calc(self): constants = {} #self.smin1t = self.smin1 - self.dblock / 2 #self.smin2t = self.smin2 - self.dblock / 2 - #self.awork = self.umax / (self.l * self.m) - #self.fl = self.Fd * (1-self.kturn) - #self.flon = self.Fd * self.kturn constants["Fprop"] = self.k_prop * self.force_target constants["freq"] = sqrt(self.k_hardness_1 / self.mass_1) constants["eff_control"] = self.torque_max_1 / self.transmission_ratio_1 diff --git a/src/OptAlgorithm/OptTimeCalculator.py b/src/OptAlgorithm/OptTimeCalculator.py index 17ca585..5b103aa 100644 --- a/src/OptAlgorithm/OptTimeCalculator.py +++ b/src/OptAlgorithm/OptTimeCalculator.py @@ -65,11 +65,13 @@ class OptTimeCalculator(AutoConfigClass): self.allTimes["topen_2_acc"] = topen_2_acc self.allTimes["topen_2_speed"] = topen_2_speed - if s1 > l1: - raise ValueError("S1 > L1 - недопустимый сценарий") - if s2 > l2: - raise ValueError("S2 > L2 - недопустимый сценарий") - + if s1 >= l1: + raise Exception("""S1 >= L1 - недопустимый сценарий, + проверьте dist_open_after_1, dist_close_end_1""") + if s2 >= l2: + raise Exception("""S2 >= L2 - недопустимый сценарий, + проверьте dist_open_after_2, dist_close_end_2""") + s1 += Fs1 topen_1_mark = sqrt(2 * s1 / self.a_max_1) if topen_1_mark > topen_1_acc: @@ -100,15 +102,19 @@ class OptTimeCalculator(AutoConfigClass): vF0 = v0 * self.k_hardness_1 vFmax = min(self.v_max_1 * self.k_hardness_1, sqrt(self.k_hardness_1/(self.mass_1))* self.Ftogrow) - l = sqrt(self.eff_control ** 2 + self.mass_1/self.k_hardness_1 * vF0**2) L = sqrt(self.k_hardness_1 / self.mass_1 * self.eff_control ** 2 + vF0*vF0) tspeed = sqrt(self.mass_1/self.k_hardness_1) * (arcsin(vFmax / L) - arccos(sqrt(self.k_hardness_1 / self.mass_1) * self.eff_control / L)) Fspeed = - self.eff_control * cos(self.freq * tspeed) + self.eff_control + 1/self.freq * vF0 * sin(self.freq * tspeed) - Fmeet = 1/self.freq * sqrt(self.freq**2 * self.Ftogrow**2 - vFmax**2) - + eps = 1e1 + if self.freq**2 * self.Ftogrow**2 - vFmax**2 < -eps: + raise Exception("""Номинальная траектория набора усилия не может быть достигнута, максимальная скорость превысила скорость траектории + , проверьте параметры k_hardness_1, mass_1, k_prop""") + Fmeet = 1/self.freq * sqrt(self.freq**2 * self.Ftogrow**2 - vFmax**2 + eps) Fstart_prop = self.Fstart_prop - assert Fmeet < Fstart_prop + if Fmeet > Fstart_prop: + raise Exception("""Номинальная траектория набора усилия была достигнута на фазе подпора + , проверьте параметры v_max_1, k_prop""") tmeet = (Fmeet - Fspeed)/vFmax tend = self.tGrowNominal(Fstart_prop) - self.tGrowNominal(Fmeet) vp = 1/sqrt(self.k_hardness_1 * self.mass_1) * sqrt(self.Ftogrow**2 - self.Fstart_prop**2) @@ -132,14 +138,15 @@ class OptTimeCalculator(AutoConfigClass): v0s = [] pos0s = [] for i in range(1,3): - tq = tmark - assert tq > 0 - v0 = closeAlgo("V"+str(i), "Open", tq) + if tmark < 0: + raise Exception("""Отрицательное время этапа раскрытия, + проверьте dist_open_after_{1,2}, time_command""") + v0 = closeAlgo("V"+str(i), "Open", tmark) v0s.append(v0) - x0 = closeAlgo("X"+str(i), "Open", tq) + x0 = closeAlgo("X"+str(i), "Open", tmark) x1 = contact[i-1] - self.__dict__["dist_close_end_"+str(i)] x = x1 - x0 - pos0s.append(closeAlgo("X"+str(i), "Open", tq)) + pos0s.append(closeAlgo("X"+str(i), "Open", tmark)) Tfull = self.time_robot_movement @@ -155,7 +162,9 @@ class OptTimeCalculator(AutoConfigClass): t3 = (Tfull + v0 / a) / 2 sqrtval = a**2 * (a**2 * (Tfull+2*t3)**2 - 8 * a * Sfull + 2 * a* v0 * (Tfull+2*t3) - 3 *v0**2) - assert sqrtval >= 0 + if sqrtval < 0: + raise Exception("""Невозможно с S_{i} добраться но H*_{i} за указанное время, + проверьте dist_open_after_{i}, dist_close_end_{i}, time_command, time_robot_movement""") t1max = ((Tfull+2*t3) + v0/a)/(2) - sqrt(sqrtval) * sqrt(2)/(4*a**2) t1 = min(t1max, (vmax- abs(v0))/a) t1 = max(0, min(t1, -v0/a + sqrt(v0**2 / (a**2) + (abs(maxL)-v0*v0/a)/a))) @@ -180,7 +189,7 @@ class OptTimeCalculator(AutoConfigClass): t2 = max(0, min(t2max, (abs(maxL) - abs(Smovement))/v1)) t4 = max(0, Sleft/v3 + v1/v3 * t2) - tstay = Tfull - t1 - t2 - t3 - t4 - t5 + tstay = max(0, Tfull - t1 - t2 - t3 - t4 - t5) self.allTimes["tmovement_"+str(i)+"_acc"] = t1 self.allTimes["tmovement_"+str(i)+"_speed"] = t2 From bd65193bf0eab40f1294d566991edc286b99f746 Mon Sep 17 00:00:00 2001 From: ermolaev_p Date: Fri, 15 Nov 2024 16:38:34 +0300 Subject: [PATCH 03/13] =?UTF-8?q?fix(SF-483):=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=81=20=D1=80=D0=B0=D1=81=D1=87=D0=B5=D1=82?= =?UTF-8?q?=D0=BE=D0=BC=20=D1=82=D1=80=D0=B0=D0=B5=D0=BA=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=B7=D0=B0=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/OptAlgorithm/OptAlgorithm.py | 3 ++- src/OptAlgorithm/OptTimeCalculator.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OptAlgorithm/OptAlgorithm.py b/src/OptAlgorithm/OptAlgorithm.py index c86e411..e0e8108 100644 --- a/src/OptAlgorithm/OptAlgorithm.py +++ b/src/OptAlgorithm/OptAlgorithm.py @@ -116,7 +116,8 @@ class OptAlgorithm(AutoConfigClass): dF0 = self.a_max_1 * self.Ts["tclose_1_acc"] * self.k_hardness_1 dFmax = min(self.v_max_1 * self.k_hardness_1, sqrt(self.k_hardness_1/(self.mass_1))* self.Ftogrow) - self.Fmeet = 1/ self.freq * sqrt(self.freq**2 * self.Ftogrow**2 - dFmax**2) + eps = 1e1 + self.Fmeet = 1/ self.freq * sqrt(self.freq**2 * self.Ftogrow**2 - dFmax**2 + eps) tspeed = self.Ts["tspeed"] Fspeed = - self.eff_control * cos(self.freq * tspeed) + self.eff_control + 1/self.freq * dF0 * sin(self.freq * tspeed) if t < self.Ts["tspeed"]: diff --git a/src/OptAlgorithm/OptTimeCalculator.py b/src/OptAlgorithm/OptTimeCalculator.py index 5b103aa..d5b93af 100644 --- a/src/OptAlgorithm/OptTimeCalculator.py +++ b/src/OptAlgorithm/OptTimeCalculator.py @@ -173,7 +173,7 @@ class OptTimeCalculator(AutoConfigClass): t5max = (Tfull - v0/a)/2 - t1 v1 = v0 + a * t1 S1 = v0*t1 + a*t1*t1/2 + v1*t31 - a*t31*t31/2 - S2max = abs(Sfull) + abs(S1) + S2max = Sfull + S1 t5 = min(t5max, (vmax)/a, sqrt(S2max / a)) t3 = abs(v0)/a + t1 + t5 t32 = t5 From a04517a15d9e9e47edcb4d9482aba4ccb78c3f6d Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 25 Nov 2024 14:01:09 +0300 Subject: [PATCH 04/13] =?UTF-8?q?chore:=20=D0=B7=D0=B0=20=D0=BE=D1=81?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D1=83=20=D0=B2=D0=B7=D1=8F=D1=82=20TraceDemo?= =?UTF-8?q?,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20?= =?UTF-8?q?=D0=B8=D0=B4=D0=B5=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B8=20=D0=BA=20=D1=80=D0=B5?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- params/system_params.json | 2 + .../AutoConfigClass.cpython-310.pyc | Bin 831 -> 831 bytes .../ConstantCalculator.cpython-310.pyc | Bin 1172 -> 1172 bytes .../__pycache__/OptAlgorithm.cpython-310.pyc | Bin 15481 -> 15481 bytes .../OptTimeCalculator.cpython-310.pyc | Bin 7744 -> 7744 bytes .../__pycache__/PhaseCalc.cpython-310.pyc | Bin 1130 -> 1130 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 192 -> 192 bytes src/__pycache__/__init__.cpython-310.pyc | Bin 146 -> 146 bytes src/__pycache__/main.cpython-310.pyc | Bin 3670 -> 1391 bytes .../__pycache__/controller.cpython-310.pyc | Bin 0 -> 698 bytes .../__pycache__/converter.cpython-310.pyc | Bin 0 -> 1226 bytes .../ideal_data_builder.cpython-310.pyc | Bin 0 -> 675 bytes .../__pycache__/mediator.cpython-310.pyc | Bin 0 -> 993 bytes .../__pycache__/monitor.cpython-310.pyc | Bin 0 -> 1378 bytes .../__pycache__/monitor.cpython-311.pyc | Bin 0 -> 2271 bytes src/controller/controller.py | 12 + src/controller/converter.py | 20 ++ src/controller/ideal_data_builder.py | 8 + src/controller/mediator.py | 21 ++ src/controller/monitor.py | 28 ++ src/gui/__init__.py | 3 +- src/gui/__pycache__/__init__.cpython-310.pyc | Bin 293 -> 246 bytes src/gui/__pycache__/app.cpython-310.pyc | Bin 3209 -> 3117 bytes src/gui/__pycache__/mainGui.cpython-310.pyc | Bin 0 -> 1560 bytes .../__pycache__/plot_window.cpython-310.pyc | Bin 8913 -> 8913 bytes src/gui/__pycache__/plotter.cpython-310.pyc | Bin 0 -> 5388 bytes .../__pycache__/qt_settings.cpython-310.pyc | Bin 5364 -> 5364 bytes .../settings_window.cpython-310.pyc | Bin 2511 -> 2511 bytes src/gui/app.py | 85 ----- src/gui/mainGui.py | 32 ++ src/gui/plot_window.py | 307 ------------------ src/gui/plotter.py | 158 +++++++++ src/main.py | 133 ++------ src/uml/__pycache__/__init__.cpython-310.pyc | Bin 241 -> 241 bytes src/uml/__pycache__/creator.cpython-310.pyc | Bin 3377 -> 3377 bytes .../request_generator.cpython-310.pyc | Bin 4202 -> 4202 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 269 -> 269 bytes src/utils/__pycache__/base.cpython-310.pyc | Bin 0 -> 5392 bytes .../__pycache__/base_widgets.cpython-310.pyc | Bin 0 -> 2061 bytes .../diagram_parser.cpython-310.pyc | Bin 2813 -> 2813 bytes .../__pycache__/json_tools.cpython-310.pyc | Bin 869 -> 869 bytes .../base/__pycache__/base.cpython-310.pyc | Bin 0 -> 7743 bytes .../__pycache__/base_widgets.cpython-310.pyc | Bin 0 -> 2066 bytes src/utils/base/base.py | 255 +++++++++++++++ src/utils/base/base_widgets.py | 47 +++ 45 files changed, 612 insertions(+), 499 deletions(-) create mode 100644 src/controller/__pycache__/controller.cpython-310.pyc create mode 100644 src/controller/__pycache__/converter.cpython-310.pyc create mode 100644 src/controller/__pycache__/ideal_data_builder.cpython-310.pyc create mode 100644 src/controller/__pycache__/mediator.cpython-310.pyc create mode 100644 src/controller/__pycache__/monitor.cpython-310.pyc create mode 100644 src/controller/__pycache__/monitor.cpython-311.pyc create mode 100644 src/controller/controller.py create mode 100644 src/controller/converter.py create mode 100644 src/controller/ideal_data_builder.py create mode 100644 src/controller/mediator.py create mode 100644 src/controller/monitor.py create mode 100644 src/gui/__pycache__/mainGui.cpython-310.pyc create mode 100644 src/gui/__pycache__/plotter.cpython-310.pyc delete mode 100644 src/gui/app.py create mode 100644 src/gui/mainGui.py delete mode 100644 src/gui/plot_window.py create mode 100644 src/gui/plotter.py create mode 100644 src/utils/__pycache__/base.cpython-310.pyc create mode 100644 src/utils/__pycache__/base_widgets.cpython-310.pyc create mode 100644 src/utils/base/__pycache__/base.cpython-310.pyc create mode 100644 src/utils/base/__pycache__/base_widgets.cpython-310.pyc create mode 100644 src/utils/base/base.py create mode 100644 src/utils/base/base_widgets.py diff --git a/params/system_params.json b/params/system_params.json index 017e7fb..58e2c7e 100644 --- a/params/system_params.json +++ b/params/system_params.json @@ -1,4 +1,6 @@ { + "trace_storage_path": "D:/downloads/a22", + "monitor_update_period": 100, "a_max_1": 5.41, "v_max_1": 0.108, "a_max_2": 35.81, diff --git a/src/OptAlgorithm/__pycache__/AutoConfigClass.cpython-310.pyc b/src/OptAlgorithm/__pycache__/AutoConfigClass.cpython-310.pyc index d27e9691bd21b728c702fe26491598ec8e05272b..68246f15dadafb298d85e68a579c2c46103b579b 100644 GIT binary patch delta 39 tcmdnbwx5kVpO=@50SFFAxh&*n;&ZWzamh@KFG?*aj!87yEXkzC2mrk`3FrU- delta 39 tcmdnbwx5kVpO=@50SM|B7%t>y;!ClLamh@KFG?*aj!87!EXkzC2mr)G3ON7( diff --git a/src/OptAlgorithm/__pycache__/ConstantCalculator.cpython-310.pyc b/src/OptAlgorithm/__pycache__/ConstantCalculator.cpython-310.pyc index 3946d0f52edf66c15d650b00e74fd859174c0250..22ef9194d297bc27a5d2f6cd2f44cfc392a59d6e 100644 GIT binary patch delta 27 hcmbQjIfauupO=@50SFFAxoqTaW@I$l+|S6$3;<8_1+@SG delta 27 hcmbQjIfauupO=@50SF3T8*b!oW@I$n+|S6$3;EFJj9_Fuw3*L3n-KuVR2nz{ diff --git a/src/OptAlgorithm/__pycache__/OptTimeCalculator.cpython-310.pyc b/src/OptAlgorithm/__pycache__/OptTimeCalculator.cpython-310.pyc index a50de4f3ce0bd1f273e67f0e67a6964560d06110..05c8dd596347fbfa90edc5910e6d8b3b5387e84e 100644 GIT binary patch delta 27 hcmX?LbHIi>pO=@50SFFAxoqTCVP-ViY``oa4FFzB1>67t delta 27 hcmX?LbHIi>pO=@50SF3T8*b!QVP-VkY``oa4FF@S21)<` diff --git a/src/OptAlgorithm/__pycache__/PhaseCalc.cpython-310.pyc b/src/OptAlgorithm/__pycache__/PhaseCalc.cpython-310.pyc index 137f01740ce4736847a32a6d641e7c167f6dedc1..82239915ca88532e725903ce8668863c0606f92d 100644 GIT binary patch delta 39 tcmaFG@rr{xpO=@50SFFAxlH8#%;#biiR delta 24 ecmbQlIEj%vpO=@50SF3T8&2f*VlW&;2}w*`#= diff --git a/src/__pycache__/main.cpython-310.pyc b/src/__pycache__/main.cpython-310.pyc index 2f36987a004e08b68f2ad6fd500870d8afe3832a..5c5e522fd647df44c95dfc89c5c4f4b997cc2a98 100644 GIT binary patch literal 1391 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 RY}IL4jdR`=uZB?k?7!y|wtD~o diff --git a/src/controller/__pycache__/controller.cpython-310.pyc b/src/controller/__pycache__/controller.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7317785c0b408d065c8558f4fa3245480eb75db GIT binary patch literal 698 zcmYjPO>5jR5S48CgRM6Wv{0IV;2umVw3Jdp$u9J^WZ6T&F$mY1U0h^)BWWpHa!Y?m zd+cA*wWt1toHEj~i3Kx$GnU?agEUO16N2md?R@ir67tU#%0J$5TuAu7jq^2BPB zA6{MCSb^E8e$fOY5r;#J8HPT^bW6UI-}ILL@$(`ZUF3m1(cUyaaxv&ygMFq!u2qcZ z{u1>JKlc~&Pu0Awxq_{(>UY%@NYVD2)pjtKpw@%x>b`+WtEOrmM<2mrySJH!UL3U? zt9CX|>CabBa~0z~d1_P6`?>?p?S%7g5IgB`#`(>zmWMye4QiQewNWWTf#&Twol4k dtfv}DdIwI|rk@Y?&+%;%?Tlt5qgn7Wd;oRqrj`Hz literal 0 HcmV?d00001 diff --git a/src/controller/__pycache__/converter.cpython-310.pyc b/src/controller/__pycache__/converter.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..05a99387fafeef2721b072c1d73c8874ac54e18b GIT binary patch literal 1226 zcmZ`&&2AGh5VpPE%?}CCQXvYwz+R#XaY9j5XjEe7$@uK$bnfR?4{9S^QR>leL9VExiXF0RVC0%?l5@Hs3%W_JB1EC$?{I>iA>4(m$@pOJ2E$quDLdFpd1&RP zoL99Ayl_PwB3Yk?mesRT<~n5-JCOB08&ita#UI2z0Ozl_qc@XLAqCuZ6ZvZLQI`t1 z+@Bf$LEEXZm8^3;aW^8|TQ(?Lw@$8o{t>yL=gboiY#gx#yI^2Pphs66_*qR7FcgjdN&7y; za!)}V0+F9u=hOrB3wlkzv17KsZjYT{qXM_6%uc#6@8iQeJa#^}I_-s-`NGuU2~6f-?u*h5KEu~+& Pw(%Y0u5R?s6{RW z`_jog`2;%A=?~DU5w}U6YIz0A$zRHbrHIF8DwxmOD7RL@$UZ0>pSGRxs&74(ZByAz%)(9RO}!7xWMtU^ z`^?LGcuvs6E&LK&v6a6i^(VG~QUfu`3w!jM+DYOh3`7uTh_6>F=|n=TaUZSmDOZJW(i*Y=mjSFNvAQ<@_9vLM~PZ=Ex~ z7`sDFbHnT1;8xv@e?;}Cv;wm|5p(hV#ltbI{>xiVS!$zdLsI96b*l%*{sQsapxpi@ z)wb-%!ZF*+E{$`DenA{N;9uf12A&r;ISQD;OEI3%b37yctD(0ptgh+RNAQv|}3yv7ZF*^q6j8z2oe|;n#pu;n9%cKcdxRNTk=EV z(ZAFOFP{7h9*kAJNnCB{>Z(_>)vsRHb{iWRfi-?NIsNVt@&kkQ6+keCt>1&;gi}ch z3a2N%#xHz|m@k7SEJEi8GHT)?ZjvHt(jslLBBSIj;USMM36Dg4;THo=kH|3o2^Gn~ zklOG=TX!uu@!@gJPlXuO0yaI%+&S1Kn41UO=fP!A zqK88zO8r}A@h=3fQp-d9R*@euGG zz@w}9A3Op4Dd6cZAl!b1hoVKD)QkL*E8k$hk`4JB8Epji_xnevKzDW|O*P zO7wbGKARm2$?Nv?sPD{FsClQFvaQ5St7`VQ_^i2kdTgwT0Mchjm)wK z2^@oBYq~r%&qs$h!>Qd(_5tWIT9{hu(FqK%GYbE9|1oy;*Vs66NXaHISAD;t5NUjo LgrI6W-nRb-9}4&} literal 0 HcmV?d00001 diff --git a/src/controller/__pycache__/monitor.cpython-310.pyc b/src/controller/__pycache__/monitor.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3e89e85a01971174e87209d3e3099d4ac95c0a6 GIT binary patch literal 1378 zcmZ`(&2HQ_5GE<=XV~}o zy--dL(7Z!YV14u}@tRX#p_g=qvQf8gDQIRWa)#f0GgP;~KPE8B$0w^FBSJpl%9QA&I1#G_<4?ZKhetKu0=ic*(;zuHz;t6H2}#GM33ZA`_KdL}e=3DJjxFAPOm{ zkF8c}Jp(Jz-D;%_Scl(KR-M#FEnH{LUv_N`dVvnN2ZPBAc zl7r?lhQks+xf6|o)6Kw0kTUreUi%n?BRkrYGj>Ve(jF`k!Hl29y99K42}!$bHS&TjFtWR}qove+&CqNEKiFM_E@`+g1T3MfO))G8~s~cr} zimKZ!7`TwJA&e6J-uM?&B``CUBQaj!*Ya@#It|EL1@^*4-n2Iz&WEk2Em}V zm(Y?|bXIVaz>4RgIQ*=uTZ1WFQBQxlqUIjhfn{?aw`I?D)x46`@gdACHqnG^zq(7% z4Y|*Cx2Uu|p5FM~0f;dIK)i}QW=ejhr^Mg^1vMj3=5rJeQDD6T67vOEpTZkJjLG(J zrrsQdwm6c?K?f=M?5M~?b|ytPOv@*>GqB`2HmHx9YV8y7a>|50GY7b7BpM~5pF87| zwsZCJJm4szfexgy9JT7r(8>d-01r7b`ykM;pMl8f1fJ|8XA^n=9mVOG@{ikx|4Z4d zh@tmITQy1uKNfHe0!knXW^*f_(06x?8LB&)LATUMlzPC2EP@V=i$a7 z?SY#T|3MqG8Lrs_xFpk!tF@iJf*(>4274%Y|JPB_5(C0xY&VNl%t=Obmb1g?FT{L9 Aga7~l literal 0 HcmV?d00001 diff --git a/src/controller/__pycache__/monitor.cpython-311.pyc b/src/controller/__pycache__/monitor.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..529ca51cbb8430de68dc7243505a7afee3237c02 GIT binary patch literal 2271 zcmb7FO=ufO6rR~#$t!yutFGeKKW$~up=(n$7zZ3X_z(;wgsQkoF2b;twQG0Pl~$cy zHMLPd2Sa7>vBiZp;7eV*PH9gihn{-saTNp+0|rAc?ajtHl$`ozq+M&{rqJ2hH*emX zdHdd*Z{B`CIM|P%ef#J9dPYR(4>s{zq|2OVfZ0Vl(y@g~IEOLg1xv^YFp8E~l5!H4 zNmis3%|$U1(0fRaY#}{rMEAk&5xkw2>(hlSQv3d5Qx(&QV;M#z16m&|cJ+^^UN%&!2~_V&uN! zYY-~Nd|t;duG103C}cK=yE#glkSa6p8v3N#PX*hdeU|CCx=HAe2DFn?rcrIp zveMkTYnW~%~~9K%|p5pKg_=}9J^ z-_Yk*mdw0HjEb{zm*fk^l2NjIIENHgz^+Sd%QDDH*KoSBK?gMEy5_jx%I3t2XO`~K z4#2k@hR8ZPjt_s?|MhHZ{M}~!S}T675owQ%H>90`6Ip4=qb+&zsjNPc)q~Wdcbf8C zOP=%Oxnudt&VZMAyD6(JS@ryW4i-@%I9Zsm4{>bV0_hhoMaTAkpu-JL7$G+}N8p+5 zZfl@547iouL0^IpmkC>P4evv0k1o&`o`tX&#>NAoCXgHM(1p#S?DM)<6TU$Yh42oH zAd0!Xj3?V(j7UccPcd2K_iS+=U2K%h63g_g45DGO~SzLR;XOg>R2_fiM3rZUq~W;|u4J@!^( zY3ELR2=?RH8||?PHf_LjD#Dx#IV3V_1WKz`&X){Lqx~9GS-om8UeUBqt9h%VA?)mU zZVo$8>LiQR6~YJuxibT#9z3T~Br+zoC-m8rzbKRb}lyF9gWQuVN!u}2F1h7cbAY*mZ*#H7jW86j~UbweWtj?bkH0p)>37Yc4 X{WLm^A%e@qdu{rRiJ$$8j=S~`8Ib&6 literal 0 HcmV?d00001 diff --git a/src/controller/controller.py b/src/controller/controller.py new file mode 100644 index 0000000..bafe0ff --- /dev/null +++ b/src/controller/controller.py @@ -0,0 +1,12 @@ +from PyQt5.QtWidgets import QWidget +from PyQt5.QtCore import pyqtSignal + +from src.utils.base.base import BaseController + + +class Controller(BaseController): + + signal_widgets = pyqtSignal(list) + + def send_widgets(self, widgets: list[QWidget]) -> None: + self.signal_widgets.emit(widgets) diff --git a/src/controller/converter.py b/src/controller/converter.py new file mode 100644 index 0000000..f281298 --- /dev/null +++ b/src/controller/converter.py @@ -0,0 +1,20 @@ +import pandas as pd + +#FIXME: костыль для выключения предупреждения "replace deprecated". Потом надо поправить. +pd.set_option('future.no_silent_downcasting', True) + +from src.utils.base.base import BaseDataConverter + + +class DataConverter(BaseDataConverter): + + @staticmethod + def _replace_bool(dataframe: pd.DataFrame) -> pd.DataFrame: + bool_columns = dataframe.columns[dataframe.isin([True, False]).any()] + dataframe[bool_columns] = dataframe[bool_columns].replace({True: 1, False: 0}) + 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) diff --git a/src/controller/ideal_data_builder.py b/src/controller/ideal_data_builder.py new file mode 100644 index 0000000..9a25ec0 --- /dev/null +++ b/src/controller/ideal_data_builder.py @@ -0,0 +1,8 @@ +from src.utils.base.base import BaseIdealDataBuilder +import pandas as pd + + +class idealDataBuilder(BaseIdealDataBuilder): + def __init__(self,operator_config: dict, system_config: dict): + super().__init__(operator_config, system_config) + self.mul = 10000 diff --git a/src/controller/mediator.py b/src/controller/mediator.py new file mode 100644 index 0000000..c564840 --- /dev/null +++ b/src/controller/mediator.py @@ -0,0 +1,21 @@ +import pandas as pd + +from typing import Union +from PyQt5.QtWidgets import QWidget + +from src.utils.base.base import BaseMediator, BaseDirectoryMonitor, BaseDataConverter, BasePlotWidget + + +class Mediator(BaseMediator): + + def notify(self, + source: Union[BaseDirectoryMonitor, BaseDataConverter, BasePlotWidget], + data: Union[list[str], list[pd.DataFrame], list[QWidget]]): + if issubclass(source.__class__, BaseDirectoryMonitor): + self._converter.convert_data(data) + + if issubclass(source.__class__, BaseDataConverter): + self._plot.build(data) + + if issubclass(source.__class__, BasePlotWidget): + self._controller.send_widgets(data) diff --git a/src/controller/monitor.py b/src/controller/monitor.py new file mode 100644 index 0000000..a5229af --- /dev/null +++ b/src/controller/monitor.py @@ -0,0 +1,28 @@ +from time import sleep +import os + +from loguru import logger + +from src.utils.base.base import BaseDirectoryMonitor + + +class DirectoryMonitor(BaseDirectoryMonitor): + + def _init_state(self): + files = os.listdir(self._directory_path) + self._files = files + + self.update_timer.timeout.connect(self._monitor) + logger.info("Monitor initiated!") + + def _monitor(self): + files = os.listdir(self._directory_path) + new_files = sorted(list(map(lambda x: os.path.join(self._directory_path, x), + filter(lambda x: x not in self._files, files)))) + if new_files: + logger.info(f"New files detected: {new_files}") + self._mediator.notify(self, new_files) + self._files = files + if not files: + self._files = [] + diff --git a/src/gui/__init__.py b/src/gui/__init__.py index 58fa804..03363c8 100644 --- a/src/gui/__init__.py +++ b/src/gui/__init__.py @@ -1,3 +1,2 @@ -from .plot_window import Plotter +from .plotter import PlotWidget from .settings_window import settingsWindow -from .app import tabWidgetGenerator diff --git a/src/gui/__pycache__/__init__.cpython-310.pyc b/src/gui/__pycache__/__init__.cpython-310.pyc index ccbb522b5b1ca8de813d923f506b3f978f2fdbef..4d2a80231dae29a24aa945a59b19a4be71e68f62 100644 GIT binary patch delta 125 zcmZ3=^o@}>pO=@50SGR7xTO0{$ovbzLlIAc;Mt2;^BV;3_Mq?0mR4&ZUuM4d&71GNyw}6;huqk89Sxr^x0~%d zZ{7W}v)qZZhhfkbnXIvQY(suxwke+zA80JAM{M;`rIRPlpfVVYi)*$rbC{&PmGAASh5GH+`9ABJvXsJWBIo zDzYY~hJFf`F~_Yq?li--4C=&GkXh`+JX6#OqWX}!k2Y4qh;D%aB8y1gjRWBoRDCc? zq=lCZr2>w5h0_>3|6#8i$Gxq-gzIW7t delta 1051 zcmZWoOHb5L6mC16PTP4hpbX%HS0*U|q7e|?7;vI7#stO0#7t-^y$r>fX>)oJHAEJy z+@R*J+_=|-g)wgZ4eH8t>CTN?6A96C?hp}e(=Yda=l$qzr-l5@)9vsN9| zFvFx6MhrY2!hvFvKVm0-XgfW9sQ7cLcClUyJQr9L*S)jiWoo+6kAj?9Qf+)os`!%H z8B5CXYPjLXjPsz~h~1U-_VTx1_&6qXQ9#3sBG&eyES~GmbU{)Zf!|=<(V#+CJ@WV} zP|yxgl*C2_x1-lDzU%KVkt&Qzec$6=Vh29+nl2Ao>|fimOU8fXl-H2>n*O-eOFm8! zqzLllErY4o&>?iwEsK`(Vc4t%%N%-$$su#48G2k&$A~H*bqj;v4qD_Jj!QpC-Uxl> zq-0evOr(L+h#4FtNW}wH2ZIRJch@rK)Zs}yVy~u&rgNu8>mDZI`jo}Ecx6_%4&~#d zG(&KnV3yzlLZY|57IVr_q>F{=EXehM9BGsYs9-P%CJ>S|c>j<`55KEcf;*s@&IU($^I|C?(5dtbE(VIcclk^HrNmeHNE5l2lf9;2i zC`VwSC4DhvX)2~_mPAkX?d)apXteI%oQtAF$3H6SL>fXK=1Hithiv&jpJG2dlD}%J M2L2nSnp5??--Xcz5&!@I diff --git a/src/gui/__pycache__/mainGui.cpython-310.pyc b/src/gui/__pycache__/mainGui.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..913dfe6c9ef3a8f2c0a07be43e70aab75e796fad GIT binary patch literal 1560 zcmZ8hU60#D6rJ%`?0m7MMct|uf`=d?K~y1CLI@$$4Z9#{v?0(HR?x`JOoF#goX$*G zvhqH4rT&fNasSf1^2A@*7r1x4q27))*LUoD$M>8$*LkZ|Coq0~+@D>$g#3+*>hNIk zElkx1!wIJunUk1O^qtI^yRmD1H}mFx>|5WZ&Se<8ylKDg#U8H-Uj(PM2ZX!an|eIt(WM9V)Oq8Q#L*k#k+=@EwM@P8MQZmi z4f?>3o$4cSGnc>I8s70 zrPmpv_ms${SHJ>elPpn+u`6=@W&f*jKTVhvOEpfu7@vrYr;FKWnd@UAr@5Rbi-{O3 zIT_DZ>39xI9j(&daxEh$FNCQAFm)QzHa)-l7FX|WF;eK2Tnr{vqz)t@(gWP#GcelX zEC_SJbGPJz7Ifnk38p410j!o|2(4ksWgcMwOTL#Aai5$ya<=Qq}wvkw2f^F8Z4W1UgAQPNc#-Vo6k9?6uK zRLFZ!ocsXI`(R7}d;zP*;o7*1{LF+(%PDqIya)UptfUl+n_lYrmPUCW6B`vSj0>k> zycvAu9d1oq{gIzB8w)Y&E~KhGFd@(!(mGs^fNbyj{6U58+c~$0M$&OwqCW%&v_rN; z(^KcABU_*zP!#?(Ms}9^@r?UYtR;5134Ro7cKF2jlT0LXrwk`~{BGqfNI8~5sqg*- z1|C7K)qfk*;r)BQUn%!iAnb_v2HggB=^~j6=+Zi4^PI0T^qY*mS|wTe#`cyKpz*R4 zs7Im8eKa4V`2>t<-L&yUWEo?XI-3|`C5)Ykt)fuNA!*XOzaQ*H5}yyckwnVmLomia zUJvz?QXx(2_lEi)m%`E$KZO48t#q2H-V69&TC-EUM3vhuD>c|&!WvBYb&2sC?0#EF MlQf+s@O97m5BIG4I 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 literal 0 HcmV?d00001 diff --git a/src/gui/__pycache__/qt_settings.cpython-310.pyc b/src/gui/__pycache__/qt_settings.cpython-310.pyc index 0a6353d4b8c694d7a200b2e36b2a4aa1992e7134..c37cdc555af06dafece7a0bb5a8607b0891d1591 100644 GIT binary patch delta 90 zcmeyO`9+gEpO=@50SFd&xNPKpFU)vr@^9gE>nMJw%=F;W1nr!5LFU%M<`L}So^(}s<%=F;Wj@kOZx#W9J7ljn+r0|0N!9#H@Q diff --git a/src/gui/__pycache__/settings_window.cpython-310.pyc b/src/gui/__pycache__/settings_window.cpython-310.pyc index 15e1b4b7e8afd2289525da6e88fab8f87d4d9fd7..aca61fa8473ec56fcfd91b6c45c8eeddef523c11 100644 GIT binary patch delta 33 ncmX>vd|sG4pO=@50SFFAxoqTK%*1H4c|Fr2HpW|%gE(seld1`4 delta 33 ncmX>vd|sG4pO=@50SF3T8*b!Y%*1H8c|Fr2HpZyQL7cS!nI8#N diff --git a/src/gui/app.py b/src/gui/app.py deleted file mode 100644 index d29b0ed..0000000 --- a/src/gui/app.py +++ /dev/null @@ -1,85 +0,0 @@ -import pyqtgraph as pg - -from src.utils import read_json, DiagramParser -from src.uml import Request, UMLCreator -from src.OptAlgorithm import OptAlgorithm -from src.gui import Plotter, settingsWindow - - -class tabWidgetGenerator: - def __init__(self, directory_to_save): - self.UMLgenerator = Request(server_url='http://www.plantuml.com/plantuml/svg/') - self.uml_creator = UMLCreator(request_generator=self.UMLgenerator, path_to_save=directory_to_save) - self.operator_params = read_json("params/operator_params.json") - self.system_params = read_json("params/system_params.json") - self.operSettings = settingsWindow("params\operator_params.json", 'Operator', self._update) - self.sysSettings = settingsWindow("params\system_params.json", 'System', self._update) - - self.paths = [] - self.plotters = [] - self.bool_dicts = [] - self.float_dicts = [] - self.timings_dicts = [] - self.modes = [] - self.names = [] - - def get_widget(self, path): - self.paths.append(path) - self.plotters.append(Plotter(show_settings_func=self._show_settings)) - self._getParsedData(path) - self._update() - return self.plotters[-1].widget - - def _get_ideal_timings(self, opt: OptAlgorithm) -> list[float]: - data = opt.Ts - ideal_time = [data['tclose'], data['tgrow'], opt.getMarkOpen(), data["tmovement"]] - return ideal_time - - def _getParsedData(self, path): - self.names.append(path) - parser = DiagramParser(system_config=self.system_params) - parser.setData(path) - self.bool_dicts.append(parser.getBoolDict()) - self.float_dicts.append(parser.getFloatDict()) - self.timings_dicts.append(parser.getRealTimings()) - self.modes.append(parser.getMode()) - - - def _update(self, _ = None): - self.operator_params = self.operSettings.getParams() - self.system_params = self.sysSettings.getParams() - - opt_algorithm = OptAlgorithm(operator_config=self.operator_params, system_config=self.system_params) - ideal_times = self._get_ideal_timings(opt_algorithm) - - for i in range (len(self.plotters)): - self.plotters[i].update_data(operator_config=self.operator_params, - system_config=self.system_params, - opt=opt_algorithm, - bool_dict=self.bool_dicts[i], - ideal_time=ideal_times, - float_dict=self.float_dicts[i], - mode = self.modes[i], - timings_dict=self.timings_dicts[i]) - - self.uml_creator.update_uml(operator_config=self.operator_params, - system_config=self.system_params, - ideal_time=ideal_times, - bool_dict=self.bool_dicts[i], - float_dict=self.float_dicts[i], - mode = self.modes[i], - timings_dict=self.timings_dicts[i], - name = self.names[i]) - - - def _show_settings(self): - self.operSettings.show() - self.sysSettings.show() - - -if __name__ == '__main__': - pg.mkQApp("Plotting") - temp = tabWidgetGenerator() - widget = temp.get_widget("trace_samples/2024_11_08-19_30_49.csv") - widget.show() - pg.exec() \ No newline at end of file diff --git a/src/gui/mainGui.py b/src/gui/mainGui.py new file mode 100644 index 0000000..35c68f2 --- /dev/null +++ b/src/gui/mainGui.py @@ -0,0 +1,32 @@ +from datetime import datetime as dt + +from PyQt5 import QtWidgets +from PyQt5.QtCore import Qt +from src.utils.base.base_widgets import BaseMainWindow + +class MainWindow(BaseMainWindow): + def __init__(self): + super().__init__() + self.initUI() + self.set_style(self) + + def initUI(self) -> None: + self.tabWidget = QtWidgets.QTabWidget() + layout = QtWidgets.QVBoxLayout() + layout.addWidget(self.tabWidget) + self.setLayout(layout) + + def show_plot_tabs(self, plot_widgets: list[QtWidgets.QWidget]) -> None: + for plot_widget in plot_widgets: + tab = QtWidgets.QWidget() + grid = QtWidgets.QGridLayout() + grid.addWidget(plot_widget) + tab.setLayout(grid) + self.tabWidget.addTab(tab, "SF_trace_" + dt.now().strftime('%Y_%m_%d-%H_%M_%S')) + self.tabWidget.setCurrentWidget(tab) + + def keyPressEvent(self, a0): + if a0.key() == Qt.Key_F5: + self.clear() + + diff --git a/src/gui/plot_window.py b/src/gui/plot_window.py deleted file mode 100644 index 3d5c0dc..0000000 --- a/src/gui/plot_window.py +++ /dev/null @@ -1,307 +0,0 @@ -import pyqtgraph as pg -from pyqtgraph.Qt import QtWidgets -from PyQt5.QtCore import Qt -import numpy as np - -from src.gui import qt_settings as qts - -from src.OptAlgorithm import OptAlgorithm - - -class Plotter: - def __init__(self, show_settings_func): - pg.setConfigOptions(antialias=True) - self.alpha = 100 #[0-255 прозрачность фона] - self._init_ui() - self.settings_button.clicked.connect(show_settings_func) - - - def update_data(self, - system_config : dict, - operator_config: dict, - opt: OptAlgorithm, - ideal_time: list[float], - bool_dict: dict, - float_dict: dict, - timings_dict: dict, - mode: bool): - self.opt = opt - self.bool_dict = bool_dict - self.float_dict = float_dict - self.timings_dict = timings_dict - self.idealTime = ideal_time - self.theor_mode = mode - self.scaler = int(system_config['UML_time_scaler']) - self.WeldTime = operator_config['time_wielding'] #[sec] - self.WeldData = self.opt.calcPhaseGrow(self.idealTime[1]) - self._updatePlots() - - - def _init_ui(self): - self.widget = QtWidgets.QWidget() - layout = QtWidgets.QVBoxLayout() - self.widget.setLayout(layout) - - self.win = pg.GraphicsLayoutWidget(show=True, title="") - self.win.resize(1000,600) - self.win.setWindowTitle('') - - layout.addWidget(self.win) - self.settings_button = QtWidgets.QPushButton("Show settings") - self.settings_button.setFixedWidth(160) - info_layout = QtWidgets.QHBoxLayout() - layout.addLayout(info_layout) - info_layout.addWidget(self.settings_button, alignment = Qt.AlignLeft) - info_layout.setSpacing(20) - self.efficiency = QtWidgets.QLabel() - info_layout.addWidget(self.efficiency, alignment = Qt.AlignRight) - - - - - self.p11, self.l11 = self._init_graph('Electrode force, closure', 'Force', 'N', 'Time', 'ms') - #self.p21, _ = self._init_graph('Electrode force, compression', 'Force', 'N', 'Time', 'ms') - #self.p31, _ = self._init_graph('Electrode force, compression', 'Force', 'N', 'Time', 'ms') - self.win.nextRow() - self.p12, self.l12 = self._init_graph('Rotor Position, closure', 'Posicion', 'mm', 'Time', 'ms') - #self.p22, _ = self._init_graph('Rotor Position, compression', 'Posicion', 'mm', 'Time', 'ms') - #self.p32, _ = self._init_graph('Rotor Position, compression', 'Posicion', 'mm', 'Time', 'ms') - self.win.nextRow() - self.p13, self.l13 = self._init_graph('Rotor Speed, closure', 'Speed', 'mm/s', 'Time', 'ms') - #self.p23, _ = self._init_graph('Rotor Speed, compression', 'Speed', 'mm/s', 'Time', 'ms') - #self.p33, _ = self._init_graph('Rotor Speed, compression', 'Speed', 'mm/s', 'Time', 'ms') - self.win.nextRow() - - self.p12.setXLink(self.p11) - self.p13.setXLink(self.p11) - - self.p11.setAutoVisible(x=False, y=True) - self.p12.setAutoVisible(x=False, y=True) - self.p13.setAutoVisible(x=False, y=True) - self.widget.setStyleSheet(qts.dark_style) - - def _init_graph(self, title, Yname, Yunits, Xname, Xunits): - plot = self.win.addPlot(title = title) - plot.showGrid(x=True, y=True) - plot.setLabel('left', Yname, units=Yunits) - plot.setLabel('bottom', Xname, units=Xunits) - legend1 = pg.LegendItem((80,60), offset=(70,20)) - legend1.setParentItem(plot) - return plot, legend1 - - def _updatePlots(self): - self.p11.clear() - self.l11.clear() - self.p12.clear() - self.l12.clear() - self.p13.clear() - self.l13.clear() - - if not self.theor_mode: - self._plotRealData() - self._form_idealdatGraph() - self._calcOurScore() - - def _calcOurScore (self): - success = [] - start = np.array(self.timings_dict["closure"])[:, 0] - end = np.array(self.timings_dict["opening"])[:, 1] - points_timings = end-start - - ideal_time = sum(self.idealTime[:3])+self.WeldTime - for point in points_timings: - success.append(int(ideal_time/point * 100)) - if len(success) > 1: - maxS = max(success) - minS = min(success) - average = int(sum(success[:])/len(success)) - self.efficiency.setText(f'Efficiency Maximum: {maxS}%, Average: {average}%, Minimum: {minS}%' ) - else: - self.efficiency.setText(f'Efficiency Maximum: {success[0]}' ) - self.efficiency.setStyleSheet(qts.BigSuccessLabel) - - - def _form_idealdatGraph(self): - - if self.theor_mode: - self.timings_dict["closure"] = [[0, self.idealTime[0]]] - self.timings_dict["compression"] = [[self.idealTime[0], sum(self.idealTime[:2])]] - self.timings_dict["welding"] = [[sum(self.idealTime[:2]), sum(self.idealTime[:2])+self.WeldTime]] - self.timings_dict["opening"] = [[sum(self.idealTime[:2])+self.WeldTime, sum(self.idealTime[:3])+self.WeldTime]] - - delta = 10 #points_per_ms - for key, items in self.timings_dict.items(): - for item in items: - item_data = [] - time_data = [] - - if key == 'closure': - ideal_time = self.idealTime[0] - calc = self.opt.calcPhaseClose - color = qts.RGBA[0] - for i in range(0, int(ideal_time*self.scaler)*delta): - time = i/delta - item_data.append(calc(time/self.scaler)) - time_data.append(time+item[0]*self.scaler) - #print (item_data[-1], time_data[-1]) - self._plotIdealData(np.array(time_data), np.array(item_data).T) - self._addBackgroundSplitter([item[0]*self.scaler,item[0]*self.scaler + time], color) - - elif key == 'compression': - ideal_time = self.idealTime[1] - calc = self.opt.calcPhaseGrow - color = qts.RGBA[1] - - for i in range(int(ideal_time*self.scaler)*delta, 0, -1): - time = i/delta - item_data.append(calc(time/self.scaler)) - time_data.append(item[1]*self.scaler-(ideal_time*self.scaler-time)) - #print (item_data[-1], time_data[-1]) - self._plotIdealData(np.array(time_data), np.array(item_data).T) - self._addBackgroundSplitter([(item[1]-ideal_time)*self.scaler, item[1]*self.scaler], color) - - temp = item_data[0][4] - x = [time_data[0], time_data[-1], time_data[-1]-0.0001] - y = [temp, temp, temp] - a1, b1, c1 = self._calculate_equidistant(x, y, 2.5, 3) - self.p11.addItem(a1) - self.p11.addItem(b1) - self.p11.addItem(c1) - - elif key == 'welding': - ideal_time = self.WeldTime - calc = self._returnWeldData - color = qts.RGBA[2] - - for i in range(0, int(ideal_time*self.scaler)*delta): - time = i/delta - item_data.append(calc(time/self.scaler)) - time_data.append(time+item[0]*self.scaler) - #print (item_data[-1], time_data[-1]) - self._plotIdealData(np.array(time_data), np.array(item_data).T) - self._addBackgroundSplitter([item[0]*self.scaler,item[0]*self.scaler + time], color) - - x = [time_data[0], time_data[-1], time_data[-1]+0.0001] - y = [item_data[0][4], item_data[0][4], item_data[0][4]] - a1, b1, c1 = self._calculate_equidistant(x, y, 0.75, 3) - self.p11.addItem(a1) - self.p11.addItem(b1) - self.p11.addItem(c1) - - elif key == 'opening': - calc = self.opt.calcPhaseOpen - ideal_time = self.idealTime[2] - ideal_closure = self.idealTime[3] - color = qts.RGBA[3] - color_closure = qts.RGBA[4] - - for i in range(0, int(ideal_time*self.scaler)*delta): - time = i/delta - item_data.append(calc(time/self.scaler)) - time_data.append(time+item[0]*self.scaler) - #print (item_data[-1], time_data[-1]) - self._plotIdealData(np.array(time_data), np.array(item_data).T) - self._addBackgroundSplitter([item[0]*self.scaler,item[0]*self.scaler + time], color) - - item_data = [] - time_data = [] - for i in range(0, int(ideal_closure*self.scaler)*delta): - time = i/delta - item_data.append(self.opt.calcPhaseMovement(time/self.scaler)) - time_data.append(time+item[1]*self.scaler) - self._plotIdealData(np.array(time_data), np.array(item_data).T) - self._addBackgroundSplitter([item[1]*self.scaler,item[1]*self.scaler + time], color_closure) - - def _returnWeldData(self, _): - return self.WeldData - - - - def _plotRealData(self): - for i, (key, dat) in enumerate(self.float_dict.items()): - dat = np.array(dat).T - dat[0] = dat[0]*self.scaler - curve = pg.PlotDataItem(dat[0], dat[1], pen=pg.mkPen(color=qts.colors[i], width=2), name=key, autoDownsample=True, downsample=True) - if 'Electrode Force' in key: - self.p11.addItem(curve) - self.l11.addItem(curve, key) - elif 'Rotor Position' in key: - self.p12.addItem(curve) - self.l12.addItem(curve, key) - elif 'Rotor Speed' in key: - self.p13.addItem(curve) - self.l13.addItem(curve, key) - return dat[0] - - def _plotIdealData(self, time, data): - x_fe = pg.PlotDataItem(time, data[0]*1000, pen=pg.mkPen(color=qts.colors[8], width=2), name='x_fe', autoDownsample=True, downsample=True) - x_me = pg.PlotDataItem(time, data[1]*1000, pen=pg.mkPen(color=qts.colors[9], width=2), name='x_me', autoDownsample=True, downsample=True) - v_fe = pg.PlotDataItem(time, data[2]*1000, pen=pg.mkPen(color=qts.colors[8], width=2), name='v_fe', autoDownsample=True, downsample=True) - v_me = pg.PlotDataItem(time, data[3]*1000, pen=pg.mkPen(color=qts.colors[9], width=2), name='v_me', autoDownsample=True, downsample=True) - f = pg.PlotDataItem(time, data[4], pen=pg.mkPen(color=qts.colors[8], width=2), name='f', autoDownsample=True, downsample=True) - - self.p11.addItem(f) - #self.l11.addItem(f, 'Ideal force') - - self.p12.addItem(x_fe) - #self.l12.addItem(x_fe, 'FE POS') - self.p12.addItem(x_me) - #self.l12.addItem(x_me, 'ME POS') - - self.p13.addItem(v_fe) - #self.l13.addItem(v_fe, 'FE VEL') - self.p13.addItem(v_me) - #self.l13.addItem(v_me, 'ME VEL') - #self._addBackgroundSplitter() - #self._addEquidistances(time, data) - - def _addBackgroundSplitter(self, x, color): - alpha = self.alpha - y01 = np.array([10000, 10000]) - y0_1 = np.array([-10000, -10000]) - a01 = pg.PlotDataItem(x, y01, pen=pg.mkPen(color=qts.colors[8], width=2), name=' ') - a0_1 = pg.PlotDataItem(x, y0_1, pen=pg.mkPen(color=qts.colors[8], width=2), name=' ') - bg1 = pg.FillBetweenItem(a01, a0_1, color+(alpha,)) - bg2 = pg.FillBetweenItem(a01, a0_1, color+(alpha,)) - bg3 = pg.FillBetweenItem(a01, a0_1, color+(alpha,)) - self.p11.addItem(bg1) - self.p12.addItem(bg2) - self.p13.addItem(bg3) - - self.p11.setYRange(-1000, 5000) - self.p12.setYRange(-50, 250) - self.p13.setYRange(-400, 400) - - - def _makeFiller(self, x1, y1, x2, y2, color): - alpha = self.alpha - eq1 = pg.PlotDataItem(x1, y1, pen=pg.mkPen(color='#000000', width=1)) - eq2 = pg.PlotDataItem(x2, y2, pen=pg.mkPen(color='#000000', width=1)) - bg = pg.FillBetweenItem(eq1, eq2, qts.RGBA[color]+(alpha,)) - return eq1, eq2, bg - - - def _calculate_equidistant(self, x, y, percent, color): - if len(x) != len(y): - raise ValueError("x и y должны быть одного размера") - distance = max(y)/100*percent - x_eq1 = [] - y_eq1 = [] - x_eq2 = [] - y_eq2 = [] - - for i in range(0, len(x) - 1): - dx = x[i + 1] - x[i] - dy = y[i + 1] - y[i] - length = np.sqrt(dx ** 2 + dy ** 2) - sinA = dy/length - sinB = dx/length - - nx = -sinA*distance - ny = sinB*distance - x_eq1.append(x[i] + nx) - y_eq1.append(y[i] + ny) - x_eq2.append(x[i] - nx) - y_eq2.append(y[i] - ny) - - return self._makeFiller(np.array(x_eq1), np.array(y_eq1), np.array(x_eq2), np.array(y_eq2), color) \ No newline at end of file diff --git a/src/gui/plotter.py b/src/gui/plotter.py new file mode 100644 index 0000000..4b44628 --- /dev/null +++ b/src/gui/plotter.py @@ -0,0 +1,158 @@ +import pandas as pd +from PyQt5.QtWidgets import QWidget, QVBoxLayout +import pyqtgraph as pg +import numpy as np +from numpy import floating +from typing import Optional, Any, NamedTuple + +from src.utils.base.base import BasePlotWidget + + +class ProcessStage(NamedTuple): + mean_value: floating[Any] + start_index: int + finish_index: int + +class PlotWidget(BasePlotWidget): + + def _create_stage_ideal(self, + stage: str, + signal: str, + times: pd.Series, + dataframe: pd.DataFrame) -> Optional[pg.LinearRegionItem]: + stage_diff = np.diff(dataframe[stage]) + start_index = np.where(stage_diff == 1)[0] + finish_index = np.where(stage_diff == -1)[0] + data = self._stage_ideals[stage]() + + if start_index.size: + start_timestamp = times[start_index[0]] + finish_timestamp = times[finish_index[0]] if finish_index.size else times[len(times) - 1] + plot = pg.PlotDataItem(x=start_timestamp+data["time"], y=data[signal["name"]], pen=signal["pen"]) + return plot + return None + + + def _create_stage_region(self, + stage: str, + times: pd.Series, + dataframe: pd.DataFrame) -> Optional[pg.LinearRegionItem]: + stage_diff = np.diff(dataframe[stage]) + start_index = np.where(stage_diff == 1)[0] + finish_index = np.where(stage_diff == -1)[0] + + if start_index.size: + start_timestamp = times[start_index[0]] + finish_timestamp = times[finish_index[0]] if finish_index.size else times[len(times) - 1] + region = pg.LinearRegionItem([start_timestamp, finish_timestamp], movable=False) + region.setBrush(pg.mkBrush(self._stage_colors[stage])) + return region + return None + + @staticmethod + def _init_plot_widget(title: str) -> (pg.PlotWidget, pg.LegendItem): + plot_widget = pg.PlotWidget(title=title) + plot_widget.showGrid(x=True, y=True) + legend = pg.LegendItem((80, 60), offset=(70, 20)) + legend.setParentItem(plot_widget.graphicsItem()) + return plot_widget, legend + + def get_stage_info(self, + stage: str, + dataframe: pd.DataFrame, + signal_name: str) -> Optional[ProcessStage]: + if stage in self._stages: + stage_diff = np.diff(dataframe[stage]) + start_index = np.where(stage_diff == 1)[0] + finish_index = np.where(stage_diff == -1)[0] + + data = dataframe[signal_name] if signal_name in dataframe.columns.tolist() else [] + + if data.size and start_index.size: + start = start_index[0] + finish = finish_index[0] if finish_index.size else (len(data) - 1) + data_slice = data[start:finish] + mean = np.mean(data_slice) + return ProcessStage(mean_value=mean, start_index=int(start), finish_index=int(finish)) + return None + + def _build_widget(self, dataframe: pd.DataFrame) -> QWidget: + widget = QWidget() + layout = QVBoxLayout() + + time_axis = dataframe["time"] + dataframe_headers = dataframe.columns.tolist() + + for channel, description in self._plt_channels.items(): + plot_widget, legend = self._init_plot_widget(title=channel) + + settings = description["Settings"] + if settings["stages"] and all([stage in dataframe_headers for stage in self._stages]): + for stage in self._stages: + region = self._create_stage_region(stage, time_axis, dataframe) + for signal in description["Ideal_signals"]: + ideal_plot = self._create_stage_ideal(stage, signal ,time_axis, dataframe) + if ideal_plot: + plot_widget.addItem(ideal_plot) + + if region: + plot_widget.addItem(region) + + + if settings["zoom"]: + if max(time_axis) < 5.0: + stages = [self.get_stage_info("Welding", + dataframe, + signal["name"]) for signal in description["Real_signals"]] + if stages: + means_raw = [stage.mean_value for stage in stages] + mean = max(means_raw) + start = time_axis[stages[0].start_index] + finish = time_axis[stages[0].finish_index] + + overshoot = pg.BarGraphItem(x0=0, + y0=mean - mean * 0.05, + height=mean * 0.05 * 2, + width=start, + brush=pg.mkBrush([0, 250, 0, 100])) + plot_widget.addItem(overshoot) + + stable = pg.BarGraphItem(x0=start, + y0=mean - mean * 0.015, + height=mean * 0.015 * 2, + width=finish - start, + brush=pg.mkBrush([0, 250, 0, 100])) + plot_widget.addItem(stable) + + plot_widget.setYRange(mean - 260, mean + 260) + plot_widget.setInteractive(False) + else: + max_value = min([max(dataframe[signal["name"]]) for signal in description["Real_signals"]]) + region = pg.LinearRegionItem([max_value - max_value * 0.015, + max_value + max_value * 0.015], + movable=False, + orientation="horizontal") + + region.setBrush(pg.mkBrush([0, 250, 0, 100])) + plot_widget.setYRange(max_value - 200, max_value + 200) + plot_widget.setXRange(3.5, 4.5) + plot_widget.addItem(region) + plot_widget.setInteractive(False) + + for signal in description["Real_signals"]: + if signal["name"] in dataframe_headers: + plot = plot_widget.plot(time_axis, dataframe[signal["name"]], pen=signal["pen"]) + legend.addItem(plot, signal["name"]) + + + + layout.addWidget(plot_widget) + + widget.setLayout(layout) + return widget + + def build(self, data: list[pd.DataFrame]) -> None: + widgets = [self._build_widget(data_sample) for data_sample in data] + self._mediator.notify(self, widgets) + + diff --git a/src/main.py b/src/main.py index a0ae44a..02bc55d 100644 --- a/src/main.py +++ b/src/main.py @@ -1,115 +1,38 @@ import sys -import os -import time -from PyQt5.QtWidgets import ( - QApplication, - QMainWindow, - QTabWidget, - QWidget, - QVBoxLayout, - QLabel, -) -from PyQt5.QtCore import Qt, QThread, pyqtSignal, QObject, QFileSystemWatcher -from PyQt5.QtGui import QIcon -from src.gui import qt_settings as qts +from PyQt5 import QtWidgets +import json +from os import path -# Импортируйте ваш класс `app` здесь -# Предполагается, что класс `app` предоставляет интерфейс для отображения данных -# Если `app` не предоставляет виджет, возможно, потребуется его модифицировать -from src.gui.app import tabWidgetGenerator - - -class DirectoryWatcher(QObject): - - file_created = pyqtSignal(str) - - def __init__(self, directory_path): - super().__init__() - self.directory_path = directory_path - self.watcher = QFileSystemWatcher() - self.watcher.addPath(self.directory_path) - self.existing_files = set(os.listdir(self.directory_path)) - self.watcher.directoryChanged.connect(self.on_directory_changed) - - - def on_directory_changed(self, _): - try: - current_files = set(os.listdir(self.directory_path)) - new_files = current_files - self.existing_files - self.existing_files = current_files - for file in new_files: - if file.lower().endswith(".csv"): - full_path = os.path.join(self.directory_path, file) - self.file_created.emit(full_path) - except Exception as e: - print(f"Ошибка при обработке изменений директории: {e}") - - -class MainWindow(QMainWindow): - def __init__(self, directory_to_watch): - super().__init__() - self.setWindowTitle("Мониторинг CSV-файлов") - self.setGeometry(100, 100, 800, 600) - - self.tabs = QTabWidget() - self.tabs.setStyleSheet(qts.dark_style) - self.tabGen = tabWidgetGenerator(directory_to_watch) - self.handle_new_file() - self.setCentralWidget(self.tabs) - - # self.setWindowIcon(QIcon("path_to_icon.png")) - self.start_directory_watcher(directory_to_watch) - - - def start_directory_watcher(self, directory_path): - self.watcher_thread = QThread() - self.watcher = DirectoryWatcher(directory_path) - self.watcher.moveToThread(self.watcher_thread) - - self.watcher.file_created.connect(self.handle_new_file) - self.watcher_thread.started.connect(self.watcher.on_directory_changed) - - self.watcher_thread.start() - - def handle_new_file(self, file_path = None): - time.sleep(0.2) - if file_path: - file_name = os.path.basename(file_path) - else: - file_path = None - file_name = 'Ideal' - - tab_widget = self.tabGen.get_widget(path=file_path) - - tab = QWidget() - layout = QVBoxLayout() - layout.addWidget(tab_widget) - - label = QLabel(f"{file_name}") - label.setAlignment(Qt.AlignCenter) - layout.addWidget(label) - tab.setLayout(layout) - - self.tabs.addTab(tab, file_name) - - def closeEvent(self, event): - self.watcher_thread.quit() - self.watcher_thread.wait() - event.accept() +from src.gui.mainGui import MainWindow +from src.controller.monitor import DirectoryMonitor +from src.controller.mediator import Mediator +from src.controller.converter import DataConverter +from src.controller.ideal_data_builder import idealDataBuilder +from src.gui.plotter import PlotWidget +from src.controller.controller import Controller +from src.utils.json_tools import read_json def main(): - directory_to_watch = "D:/downloads/a22" + app = QtWidgets.QApplication(sys.argv) + operator_params = read_json("params/operator_params.json") + system_params = read_json("params/system_params.json") + monitor = DirectoryMonitor(system_params['trace_storage_path'], system_params['monitor_update_period']) + data_converter = DataConverter() + ideal_data_builder = idealDataBuilder(operator_params, system_params) + plot_widget_builder = PlotWidget(idealDataBuilder=ideal_data_builder) + controller = Controller() + mediator = Mediator(monitor, data_converter, plot_widget_builder, controller) + monitor.start() + window = MainWindow() - if not os.path.isdir(directory_to_watch): - print(f"Директория не найдена: {directory_to_watch}") - sys.exit(1) - - app_instance = QApplication(sys.argv) - window = MainWindow(directory_to_watch) window.show() - sys.exit(app_instance.exec_()) + + controller.signal_widgets.connect(window.show_plot_tabs) -if __name__ == "__main__": + sys.exit(app.exec_()) + + +if __name__ == '__main__': main() diff --git a/src/uml/__pycache__/__init__.cpython-310.pyc b/src/uml/__pycache__/__init__.cpython-310.pyc index d8643a537f96910b494dde168309414b2e6e3708..8a313df85224227d92e95fa74b7f79f0fb1fb420 100644 GIT binary patch delta 37 rcmey!_>qx2pO=@50SFFAxlH7q#^+)cqx2pO=@50SM|B7*6D##+PChSf~2=jG*M0D=QjE)%);G8#=h=>h;ghXw@z delta 24 ecmeBW>Sf~2=jG*M0D{8Th7-B>G8#@i=>h;kod$CN diff --git a/src/utils/__pycache__/base.cpython-310.pyc b/src/utils/__pycache__/base.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6fe4f40d24c6de82b04e9bf4d42201debd9f8b1 GIT binary patch literal 5392 zcmcIo-ESMm5x;L9KP6EgPVCsBoi+_yMQM|!NsZLCBU|a06+3c~l$Ls+xht9Ok;m+v z8i;U#0ydiepy-1i5}`TC8loc-1Qr`m23)P-o154wi4}KztQeUMW5%czuy)+GHGGB@y90NBFs=DMj8!M z7_{`N$cw^#r(uhEF(YP)bHp5}v!F|FH)DBKigq)Jl+JacZX3)3sxP+{%^In_tApBn zE9(AIszfS1#~qqUb9Gqd^uj376*OEUE>%z$=$k}EVMrfw8+|a4TQ2FCJ>V@Wt5E*i z#N0LS8i8?_es_$(ylas}g(Qn4nFx&5 zv{6LWK$W_yomht33LsM@kP65wk$pog(d+Py%jY*Qx0`{Iy?C?v>gM}06z%TLMlVXP zNwpoRPP5yRo3Uzb?k4Rp-n>PYSn2I)KM2}n)*!&RF~;>=-}KD16wLl2Y?e7;CF`xd zINDV$d3b>lag!}R;gaPV*N*!ktr~e?OFM$v4_`}13EOdUGfvdja*f%ZSh-BiYpU6i zS=|6!TU#x_DSN=1RN$dU2sc<u;LwgKQJ9dBm z$imb1^}3&Wp@=cq6=iVjj~Q@qikc%*chcETqJpP<4z(^U-lg>ffi46D2C*B0F9pGe zyUj3dQP1F`Ga&Hp7=f}XPXr3Y9ueOtn3XcuwMabj3@~iQzozOe;G})eXgGOOoD$D{ zY;2pHGs+EDdg8Pwiqd`Op4rHebVig#g(aV)=f$j;V<}Hkje>Q7rGhNnDT=dVDU-zs z@yvarQ4-IJlk_fsY&b@vLIHhFLFsi}5gAZ|UNgC^ZSuG-?)C@?GDs+iXuD0=r$lNT zE@i2Q5thMls|6Ql4|w>DFkr?j#3aT&;}i2!0tCmY#qnu#Tsk`xmw|iN_{2l|5GD1T zcH`ZiRBU=Z6HMq>3dZ%z2U+ZDFW7E}GSxuYh1J`=-tZK`U&= zaS)84#}mFl?J?j~a6HSS@bj#a)jvHgs>VW4$z)e`TflwxfFH&I;DHP^h=jVSUZR?P zGu3W{ECv;n{T7u+Fr{bpUzj@iQL{X8YV}PTgu{;}t%JwVlQ@QHUPt|_MEYsA$e=Mu z>nmesKgtRu$5z!W&?)&@u<6gt?* zJ~e-3@$nyme2VqnARgrcwP>aBT1w z(Qc_%vi6KekBonfcrq0CK?dJ<(r>}1wckPS8TC9WY9MDpav%&J>4ohMMQB@=2_1nHtgf&^T^{6|mJGuz?{Mh9j4mAdNXwWst`YGm_$_z#ORG{cEqhcP z;(dG8;UwOojz=Ci_agEyk>O5*9YZ+6z3(<`>CizBr&H`Mu5|Bsw1X5gSuF5*)S(lv zNjt@&!mheLvh5S&LA^m8(|w*Z$(s--G8@cxl?pqW@RvGz{8%!~sUzapI#HrGozM79*CxDoY%xc*zQ|4MwPSH>Hb#}k$cgy}Hpd=wgC2_yaD#D?_UlXQ zl=Qv#WZ0J5I=31|G2JS3ZsWsUDf?3A2KS7*bMQGW?EpvI1Ei7zL4<0NWDWqxgP(!? zHm&^v{AVES?{%(Kfat+*K!7PTZXfllgO$`)ca@UegumXy<#&TJDlMA! zy^Zz`U4rBO!g~?jJZl?0DaCTF(|IMP-gL#d2?aMnuz+dZ)~H+mr760;SeuxCx%P`o z{p#_a<4YJ*fHtSEVPdu?4k9`iq^6+_fEl__hLMU%?1f3tx=nX{8OG{Oe8pSAD6TNb z7M1wtL<)2oEm)q)v7Y_!aiB%yron_Gyzeognx=G40~&-r8-4 z;*Xdbr>s8zIWlHXZcg+48aj<3;|F_-|l)m#%m8-+;pItIiYAUb5GtT%=$zg)^7-dd;qA#@gx$UAne+J$ZfQ zda@cRsa*8&Kyv6flQpLQeZ>l!65nq4M8_K@yN5NHrmXhgO8>67fJ_}@5hcU7W=-E( QFtO=Y7Ah}SW*0vA7grQzX#fBK literal 0 HcmV?d00001 diff --git a/src/utils/__pycache__/base_widgets.cpython-310.pyc b/src/utils/__pycache__/base_widgets.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cad539658bfac7f050f71b905450d32f2798dbc GIT binary patch literal 2061 zcmcgt!EW0|5M5G~L`k-j0znb<#3m;Jv0(|d6DUOz$ZCoLiEBYg4X`TMm3AewUGB2G z%h*cWQ~M$9v8VnIuRZk_a_S7NBx%gg#3k@ zRqQf0yyOKADPw3=0 zW^-=y`f#bVhF|s7*(178nVq7qRjI({0rLM46iz~i5#a0>JiM^N>cF6pZ}q9+k7+EA zW69KMUQ?6r_|(4mr~v-@HR`QkiTX`m)7)lS=H8)_eCn=%qK>!+h`R;KPtI?Ux!;Sd z0iJtEohl*C;0;;24t^}XLBk21em~bLlWcpcgwnm>=I)@=>D<1%)_kU<-Ja1T7K>hR zW5nl*2T#AaaVs!Xnr*{%JiFkciJ$Xc(D@`iD;xb>!W%y3#?U#3GQ2za&VHxg?UvnR ztnZclQD#p1nYBv3JNbtX4-R&B?*^q*Ap1AUv)(ABjKy*eN$#d+L3eLmrqS6%X~v=0 zXl0a$S#a~S{r(*QUyFTizO5;XGt&$1yv^~_Lg!?(DOG9wZGU_=H%THw!M zciwWIU;lT@-+5(p*!Bv1je}9+6}4jGouNISfJVbKAsWUv(REx9YX!fcgCuhQ({tMQ9M~BQYlHaiRmXR)IoI5O0Ho~Q A`Tzg` literal 0 HcmV?d00001 diff --git a/src/utils/__pycache__/diagram_parser.cpython-310.pyc b/src/utils/__pycache__/diagram_parser.cpython-310.pyc index 6ee7ca1d5602a90ff6bf674c25093913290babd6..098b2f8e6bf4cb7052119da6a19dfba5ca9cfc10 100644 GIT binary patch delta 27 hcmew>`d5@YpO=@50SFFAxoqT?Vq!Gftj2Vm0{~`d5@YpO=@50SLYYm~7;hVq!Ghtj2Vm0|0312LS*8 diff --git a/src/utils/__pycache__/json_tools.cpython-310.pyc b/src/utils/__pycache__/json_tools.cpython-310.pyc index 6def11015fb2fce733811c9c49c3cec40c262f09..45c90a34260158c49616d82f9ed124d9b52f497d 100644 GIT binary patch delta 27 hcmaFL_LPk~pO=@50SFFAxoqSvV`Mbi+{E~p5ddJ~2NM7Q delta 27 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 literal 0 HcmV?d00001 diff --git a/src/utils/base/__pycache__/base_widgets.cpython-310.pyc b/src/utils/base/__pycache__/base_widgets.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d4e21d165387499500cee27b8a26ea44e9bb152 GIT binary patch literal 2066 zcmcgt!EW0|5M5G~L`k-j0znbv#3m;Jv0(|d6DUOy$ZCoLiEBYg4X`TMm3AdFA$Qr` zWo#wwsr``l*i-*!uRZk_a_S7NBx7(jR@idL zmxNVW?H9soy!mq_++gmAwCjH%UfZ!PDuguD#8T+Pwrl;bGt_Bft4{JiM^N>cF63xB67`M>H14 zv0(Dl*5u?VpPE-U3gB!yEPBDs z5uZyQJo)P8?LbqZw>4Ms?1GCre!+V|=hN)0Z1htJZ}^C7P3IiS@Zsb;`<;HbTXv7J z{;%YZa(&XzjgjKR$v=2-aIm|3FDRt~*}qes^+p+GEEaP}ayL5*x_j#~jm{=gF%HE> zD=m|l1-HJ~@81RRwbf+q3H0(}iB5}2p?9){Z2(ZD5vc`E zHMZz2=f(AZ_WhkVMu%;$Afa$ND!igLU}<~Sk0L=+9!0hpMX6+Yg8D`j{gBh-{Ehku z?UDS-auv5eEEt={vFej8w>W8UqOVyF;{<#u str: + return self._directory_path + + @property + def update_time(self) -> int: + return self._update_time + + @property + def files(self) -> list[str]: + return self._files + + @property + def mediator(self) -> BaseMediator: + return self._mediator + + @mediator.setter + def mediator(self, mediator: BaseMediator) -> None: + self._mediator = mediator + + def _init_state(self): + files = os.listdir(self._directory_path) + self._files = files + + def start(self): + self.update_timer.start(self._update_time) + +class BaseDataConverter: + def __init__(self, mediator: Optional[BaseMediator] = None): + self._mediator = mediator + + @property + def mediator(self) -> BaseMediator: + return self._mediator + + @mediator.setter + def mediator(self, mediator: BaseMediator) -> None: + self._mediator = mediator + + def convert_data(self, files: list[str]) -> None: + ... + + +class BasePlotWidget: + def __init__(self, + mediator: Optional[BaseMediator] = None, + idealDataBuilder: Optional[BaseIdealDataBuilder] = None): + super().__init__() + self._mediator = mediator + self._opt = idealDataBuilder + + self._stages = [ + "Relief", + "Closing", + "Squeeze", + "Welding" + ] + + self._stage_colors = { + "Closing": [208, 28, 31, 100], + "Squeeze": [45, 51, 89, 150], + "Welding": [247, 183, 24, 100], + "Relief": [0, 134, 88, 100] + } + self._stage_ideals = { + "Closing": self._opt.get_closingDF, + "Squeeze": self._opt.get_compressionDF, + "Welding": self._opt.get_weldingDF, + "Relief": self._opt.get_openingDF + } + + self._plt_channels = { + "Electrode Force, N & Welding Current, kA": { + "Settings": { + "zoom": False, + "stages": True + }, + "Real_signals": [ + { + "name": "Electrode Force, N ME", + "pen": 'r', + }, + { + "name": "Electrode Force, N FE", + "pen": 'w', + }, + { + "name": "Welding Current ME", + "pen": "y", + } + ], + "Ideal_signals": [ + { + "name": "Force", + "pen": {'color': 'g', 'width':3}, + } + ] + }, + "Electrode Force, N": { + "Settings": { + "zoom": True, + "stages": False + }, + "Real_signals": [ + { + "name": "Electrode Force, N ME", + "pen": 'r', + }, + { + "name": "Electrode Force, N FE", + "pen": 'w', + } + ], + "Ideal_signals": [ + { + "name": "Force", + "pen": {'color': 'r', 'width':3}, + } + ] + }, + "Electrode Speed, mm/s": { + "Settings": { + "zoom": False, + "stages": True + }, + "Real_signals": [ + { + "name": "Rotor Speed, mm/s ME", + "pen": 'r', + "zoom": False + }, + { + "name": "Rotor Speed, mm/s FE", + "pen": 'w', + "zoom": False + } + ], + "Ideal_signals": [ + { + "name": "Rotor Speed ME", + "pen": {'color': 'y', 'width':3}, + "zoom": False + }, + { + "name": "Rotor Speed FE", + "pen": {'color': 'g', 'width':3}, + "zoom": False + } + ] + }, + } + + @property + def mediator(self) -> BaseMediator: + return self._mediator + + @mediator.setter + def mediator(self, mediator: BaseMediator) -> None: + self._mediator = mediator + + def build(self, data: list[pd.DataFrame]) -> list[QWidget]: + ... + + +class BaseController(QObject): + + def send_widgets(self, widgets: list[QWidget]) -> None: + ... + + +# FIXME: WeldingDF показывает только 1 секунду +class BaseIdealDataBuilder(OptAlgorithm): + + def _get_data(self, end_timestamp:float, func:function) -> pd.DataFrame: + data = [] + for i in range (0, int(end_timestamp*self.mul)): + time = i/self.mul + X1, X2, V1, V2, F = func(time) + data.append({"time":time, "Posicion FE":X1*1000,"Posicion ME":X2*1000, "Rotor Speed FE":V1*1000, "Rotor Speed ME":V2*1000, "Force":F}) + return pd.DataFrame(data) + + def get_closingDF(self) -> pd.DataFrame: + return self._get_data(self.Ts['tclose'], self.calcPhaseClose) + + def get_compressionDF(self) -> pd.DataFrame: + return self._get_data(self.Ts['tgrow'], self.calcPhaseGrow) + + def get_openingDF(self) -> pd.DataFrame: + return self._get_data(self.getMarkOpen(), self.calcPhaseOpen) + + def get_tmovementDF(self) -> pd.DataFrame: + return self._get_data(self.Ts['tmovement'], self.calcPhaseMovement) + + def get_weldingDF(self) -> pd.DataFrame: + data = [] + X1, X2, V1, V2, F = self.calcPhaseGrow(self.Ts['tgrow']) + data.append({"time":0, "Posicion FE":X1,"Posicion ME":X2, "Rotor Speed FE":V1, "Rotor Speed ME":V2, "Force":F}) + data.append({"time":1, "Posicion FE":X1,"Posicion ME":X2, "Rotor Speed FE":V1, "Rotor Speed ME":V2, "Force":F}) + return pd.DataFrame(data) + + def get_ideal_timings(self) -> list[float, float, float, float]: + data = self.Ts + ideal_timings = [data['tclose'], data['tgrow'], self.getMarkOpen(), data["tmovement"]] + return ideal_timings + diff --git a/src/utils/base/base_widgets.py b/src/utils/base/base_widgets.py new file mode 100644 index 0000000..5faf97d --- /dev/null +++ b/src/utils/base/base_widgets.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +import os +from typing import Optional, Union + +import pandas as pd +from PyQt5.QtWidgets import QTabWidget, QWidget, QVBoxLayout + +class BaseMainWindow(QWidget): + + def set_style(self, object: Union[QTabWidget, QWidget]) -> None: + object.setStyleSheet(""" + QWidget { + background-color: #0D1117; + font-family: "Segoe UI", sans-serif; + font-size: 14px; + } + QMessageBox { + background-color: #161B22; + font-family: "Segoe UI", sans-serif; + font-size: 14px; + } + QPushButton { + background-color: #FFCC00; + color: #0D1117; + padding: 12px 25px; + border: 2px solid #E6B800; + border-radius: 8px; + font-family: "Segoe UI", sans-serif; + font-size: 16px; + font-weight: bold; + } + QPushButton:hover:!disabled { + background-color: #FFD700; + } + QPushButton:disabled { + background-color: #555555; + color: #cccccc; + border: none; + } + QLabel { + color: #ffffff; + font-size: 16px; + font-weight: bold; + font-family: "Segoe UI", sans-serif; + } + """) \ No newline at end of file From 72b002dea3723233a7c23a804a45436c03b7eefa Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 25 Nov 2024 17:20:00 +0300 Subject: [PATCH 05/13] =?UTF-8?q?dev:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=B9=D0=BA=D0=B8,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=B0=D0=B2=D1=82=D0=BE=D0=BC=D0=B0=D1=82?= =?UTF-8?q?=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=B5=20=D0=BE=D0=B1=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- params/system_params.json | 6 +- src/__pycache__/main.cpython-310.pyc | Bin 1391 -> 1113 bytes .../__pycache__/controller.cpython-310.pyc | Bin 698 -> 698 bytes .../__pycache__/mediator.cpython-310.pyc | Bin 993 -> 1227 bytes .../__pycache__/monitor.cpython-310.pyc | Bin 1378 -> 2132 bytes src/controller/ideal_data_builder.py | 8 - src/controller/mediator.py | 7 + src/controller/monitor.py | 23 +++ src/gui/__pycache__/mainGui.cpython-310.pyc | Bin 1560 -> 2498 bytes src/gui/__pycache__/plotter.cpython-310.pyc | Bin 5388 -> 7176 bytes .../settings_window.cpython-310.pyc | Bin 2511 -> 2526 bytes src/gui/mainGui.py | 25 ++- src/gui/plotter.py | 38 ++++- src/gui/settings_window.py | 6 +- src/main.py | 13 +- .../base/__pycache__/base.cpython-310.pyc | Bin 7743 -> 11086 bytes .../__pycache__/base_widgets.cpython-310.pyc | Bin 2066 -> 2677 bytes src/utils/base/base.py | 144 +++++++++++++----- src/utils/base/base_widgets.py | 47 ------ 19 files changed, 204 insertions(+), 113 deletions(-) delete mode 100644 src/controller/ideal_data_builder.py delete mode 100644 src/utils/base/base_widgets.py diff --git a/params/system_params.json b/params/system_params.json index 58e2c7e..d0de10c 100644 --- a/params/system_params.json +++ b/params/system_params.json @@ -17,9 +17,5 @@ "position_start_2": 0.08, "k_prop": 0.05, "time_capture": 100000, - "UML_time_scaler": 1000, - "Closure_signal": "Closing", - "Squeeze_signal": "Squeeze", - "Welding_signal": "Welding", - "Release_signal": "Relief" + "UML_time_scaler": 1000 } diff --git a/src/__pycache__/main.cpython-310.pyc b/src/__pycache__/main.cpython-310.pyc index 5c5e522fd647df44c95dfc89c5c4f4b997cc2a98..e3bc4809541b8c0ce5404d3dce6c972519110706 100644 GIT binary patch delta 443 zcmYL_Jx{|h5QcrRle!;CKU6A#5EWwu>c9XJDlBvZv2@E4RU|42q^TTNEU7>$69cI7 z#(>h1KLi4P1V4ZQ&J5tw`<%|F^Lz4V>5V&yZI=k1=%zoqrweBt9v53T?Xq9FC2liV z@$Cyk90$!g0pi2pR~={Z;;KIEUKeoELLH&f2q8%h(un91W<;_%nSnHshP04W7LZJG zq$!ITWJX3amYH*NW@TnxTA~T&@^5BQCATv(a+Ux@8hJG%d2LB_<&y#Fz-b5S>dt6y zn`kWbDuQbiHJFB8&9x`f^xR7WDZ}w7RjGx zG7-;2IO>V^cB=S5+Co&o`imNH4993tQNz|d_q=!*jyfgM7`B}>Nz*oMvvp80X@CY&HK|;87#v_ngf#8uOJrtiq~xP=TqY)0MJiW> zO8!85LE4cU{{V@9K>q|cuJAexsVuMF$9~=?_WR)<-cLWsTP+{Kmpwl||79oh~ZuJqM-A8jWwUjeQQ(L(jYXZEc zJYD0p4|wXRIw-F4wWV$CXm@T;J#8%;E2vC0L96TfvNbbQyQ5&)*7Z?mg+V0Cu13pn zg$(296b+mgmv_cYvb1=VkA-9^m(gE792I$X*}oQxw}levrbI&}*_nt6IKs{aNa_{s zrFj;cJ0|0hGX+s00eO7l zQ;Utqw0)yO+WN05>RuUE+j`m%bT8QJf7so=3`m^v46#`B9S zB)jETa&*{%#KkT^6MJAGcCZiT-~gC|Jra=6l3S)!FN#tYXHhh`EnDS7>*M~tLY@sF zw~~312syl&TS!?izgRu&m*1?tiRqedn==y?Cq*^&NacA_$ZAsmvSch3Q6#(Y`v!zn f4M%CtCy981ffaWFysGjhZW8bf^DM9DWBd0Xo-fG_ diff --git a/src/controller/__pycache__/controller.cpython-310.pyc b/src/controller/__pycache__/controller.cpython-310.pyc index f7317785c0b408d065c8558f4fa3245480eb75db..27d6a3a959c8e427862a1775b88636e9c7061ffc 100644 GIT binary patch delta 19 ZcmdnRx{H-7pO=@50SHnXHgauX0st&x1a1HT delta 19 ZcmdnRx{H-7pO=@50SKZEHgauX0stzO1QY-O diff --git a/src/controller/__pycache__/mediator.cpython-310.pyc b/src/controller/__pycache__/mediator.cpython-310.pyc index 639c4a9a5fbc409b071b39ca0170703ea2d4ccf6..759eebd6d2a6ca1451e87ec9810ce50b7561cc1b 100644 GIT binary patch delta 385 zcmaFJewvdnpO=@50SHW5T+(MTPvm>e7&P&hgE&(vdn&IaLmE>GYYJNnOB7!UdoY70 z$7FlPHpZ2ck1;keica=qDy>gu0%?W<5Stl@oq@Pm4M@~5WHBsYtYKWp$OvLHA+Z@2 zFfU|aWJqBMW+>tYD%E7U#Sx#IpO;yZUv!JVv>+w1BsIP`wWK67FTJ=(0I1>?Z(4p) za%y~HPELGEW|1aSkqCo7149wW`9-2|LJX|5ptLvxu3a1`RLlk>co=yY`53Fjd{a|0 z6M+`#p(yjyCZ& z`)Tq{p2r;FEC$q2B!Wtag18(&f)j{~d4L250}~SuBh!B=Ccb}Q8BLyBYz2vVDT&2J RGLzj{LIu!`n7o=r0RW^|9ytI2 diff --git a/src/controller/__pycache__/monitor.cpython-310.pyc b/src/controller/__pycache__/monitor.cpython-310.pyc index c3e89e85a01971174e87209d3e3099d4ac95c0a6..61a2a169652f5c156fc95cafe2e309d3e6dd93eb 100644 GIT binary patch delta 832 zcmZWoO^ee&7@nC-KANTmJpIrgrPfXR zi%Vhk9HuzE`F?aiHe>4$F^kz3lsT+%O$Rn}S@RkV9A>{pf%o<2H)Byz7Rjixcr0f; zJs%P%upPRfUZ24f&j1uE(F$Rt@EcN)!cYdohrosyB2q^LG)ApKCDnI^pqFtz=t&+8 z<50+qN255*BY8R4n=Z060VbT~unk~io@6XAD+;=tJJ7T8whv`8jrlE2nL4OU z)DmT^NI?}TEk#!tqjzmZ_!DWD4#SFkLZ6`s7>~w{(p5;26 zOk2Y}4L(3+2+0F;eGpwB1`X&H*1hPA+8E XpS+b_mWvH2&B4II#KS)M0ecAmLhuj2 diff --git a/src/controller/ideal_data_builder.py b/src/controller/ideal_data_builder.py deleted file mode 100644 index 9a25ec0..0000000 --- a/src/controller/ideal_data_builder.py +++ /dev/null @@ -1,8 +0,0 @@ -from src.utils.base.base import BaseIdealDataBuilder -import pandas as pd - - -class idealDataBuilder(BaseIdealDataBuilder): - def __init__(self,operator_config: dict, system_config: dict): - super().__init__(operator_config, system_config) - self.mul = 10000 diff --git a/src/controller/mediator.py b/src/controller/mediator.py index c564840..95a79bb 100644 --- a/src/controller/mediator.py +++ b/src/controller/mediator.py @@ -19,3 +19,10 @@ class Mediator(BaseMediator): if issubclass(source.__class__, BasePlotWidget): self._controller.send_widgets(data) + + def push_settings(self, data: list[dict]): + self._monitor.update_settings(data) + self._plot.update_settings(data) + self._monitor.force_all_dir() + + diff --git a/src/controller/monitor.py b/src/controller/monitor.py index a5229af..4e24920 100644 --- a/src/controller/monitor.py +++ b/src/controller/monitor.py @@ -26,3 +26,26 @@ class DirectoryMonitor(BaseDirectoryMonitor): if not files: self._files = [] + def update_settings(self, data: list[dict]) -> None: + self.stop() + operator_params, system_params = data + self._directory_path = system_params['trace_storage_path'] + self._update_time = system_params['monitor_update_period'] + self._init_state() + self.start() + + def force_all_dir(self): + files = os.listdir(self._directory_path) + self._files = files + all_files = [] + for x in self._files: + path = os.path.join(self._directory_path, x) + all_files.append(path) + if all_files: + logger.info(f"Plotting all files: {all_files}") + self._mediator.notify(self, all_files) + else: + logger.info(f"Failed pushing {str(all_files)}") + + + diff --git a/src/gui/__pycache__/mainGui.cpython-310.pyc b/src/gui/__pycache__/mainGui.cpython-310.pyc index 913dfe6c9ef3a8f2c0a07be43e70aab75e796fad..216cde6aa43e0a694f8d6f9892327c41c8ff97f2 100644 GIT binary patch literal 2498 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 G)&c-SbT>l) delta 178 zcmca7d|sG0pO=@50SFFAxuhT1$ScIi7&TdeQOTAyg{_4liZz8jg#$>lrEsRQr!l2) zrEs^fL~*3>r0@boIf0^FKvBLFexN9KI|B None: self.tabWidget = QtWidgets.QTabWidget() 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.setLayout(layout) def show_plot_tabs(self, plot_widgets: list[QtWidgets.QWidget]) -> None: @@ -29,4 +36,20 @@ class MainWindow(BaseMainWindow): if a0.key() == Qt.Key_F5: self.clear() + def _show_settings(self): + self.operSettings.show() + self.sysSettings.show() + + def push_settings(self) -> None: + self._updater_trigger() + + def _updater_trigger(self) -> None: + self.tabWidget.clear() + operator_params = self.operSettings.getParams() + system_params = self.sysSettings.getParams() + self._mediator.push_settings(data=[operator_params, system_params]) + + + + diff --git a/src/gui/plotter.py b/src/gui/plotter.py index 4b44628..716a065 100644 --- a/src/gui/plotter.py +++ b/src/gui/plotter.py @@ -6,15 +6,42 @@ from numpy import floating from typing import Optional, Any, NamedTuple from src.utils.base.base import BasePlotWidget +from src.utils.base.base import BaseIdealDataBuilder +class idealDataBuilder(BaseIdealDataBuilder): + def get_closingDF(self) -> pd.DataFrame: + return self._get_data(self.Ts['tclose'], self.calcPhaseClose) + + def get_compressionDF(self) -> pd.DataFrame: + return self._get_data(self.Ts['tgrow'], self.calcPhaseGrow) + + def get_openingDF(self) -> pd.DataFrame: + return self._get_data(self.getMarkOpen(), self.calcPhaseOpen) + + def get_tmovementDF(self) -> pd.DataFrame: + return self._get_data(self.Ts['tmovement'], self.calcPhaseMovement) + + def get_weldingDF(self, end_time: float) -> pd.DataFrame: + data = [] + X1, X2, V1, V2, F = self.calcPhaseGrow(self.Ts['tgrow']) + data.append({"time":0, "Posicion FE":X1,"Posicion ME":X2, "Rotor Speed FE":V1, "Rotor Speed ME":V2, "Force":F}) + data.append({"time":end_time, "Posicion FE":X1,"Posicion ME":X2, "Rotor Speed FE":V1, "Rotor Speed ME":V2, "Force":F}) + return pd.DataFrame(data) + + def get_ideal_timings(self) -> list[float, float, float, float]: + data = self.Ts + ideal_timings = [data['tclose'], data['tgrow'], self.getMarkOpen(), data["tmovement"]] + return ideal_timings + + class ProcessStage(NamedTuple): mean_value: floating[Any] start_index: int finish_index: int -class PlotWidget(BasePlotWidget): +class PlotWidget(BasePlotWidget): def _create_stage_ideal(self, stage: str, signal: str, @@ -23,7 +50,7 @@ class PlotWidget(BasePlotWidget): stage_diff = np.diff(dataframe[stage]) start_index = np.where(stage_diff == 1)[0] finish_index = np.where(stage_diff == -1)[0] - data = self._stage_ideals[stage]() + data = self._stage_ideals[stage] if start_index.size: start_timestamp = times[start_index[0]] @@ -32,7 +59,6 @@ class PlotWidget(BasePlotWidget): return plot return None - def _create_stage_region(self, stage: str, times: pd.Series, @@ -50,7 +76,7 @@ class PlotWidget(BasePlotWidget): return None @staticmethod - def _init_plot_widget(title: str) -> (pg.PlotWidget, pg.LegendItem): + def _init_plot_widget(title: str) -> tuple[pg.PlotWidget, pg.LegendItem]: plot_widget = pg.PlotWidget(title=title) plot_widget.showGrid(x=True, y=True) legend = pg.LegendItem((80, 60), offset=(70, 20)) @@ -155,4 +181,8 @@ class PlotWidget(BasePlotWidget): widgets = [self._build_widget(data_sample) for data_sample in data] self._mediator.notify(self, widgets) + def update_settings(self, data: list[dict]): + self._initIdealBuilder(idealDataBuilder=idealDataBuilder, data=data) + + diff --git a/src/gui/settings_window.py b/src/gui/settings_window.py index 4c052b4..c67ba93 100644 --- a/src/gui/settings_window.py +++ b/src/gui/settings_window.py @@ -17,10 +17,10 @@ class settingsWindow(QtWidgets.QWidget): self._init_ui() self.params.sigTreeStateChanged.connect(upd_func) - def load_settings(self): + def load_settings(self) -> None: self.data = read_json(self.settingsPath) - def write_settings(self): + def write_settings(self) -> None: self.getParams() write_json(self.settingsPath, self.data) @@ -31,7 +31,7 @@ class settingsWindow(QtWidgets.QWidget): params.append({'name': 'Save', 'type': 'action'}) return params - def _init_ui(self): + def _init_ui(self) -> None: temp = self._getTreeStructure() self.params = Parameter.create(name=self.name, type='group', children=temp) self.params.param('Save').sigActivated.connect(self.write_settings) diff --git a/src/main.py b/src/main.py index 02bc55d..1200be0 100644 --- a/src/main.py +++ b/src/main.py @@ -7,7 +7,6 @@ from src.gui.mainGui import MainWindow from src.controller.monitor import DirectoryMonitor from src.controller.mediator import Mediator from src.controller.converter import DataConverter -from src.controller.ideal_data_builder import idealDataBuilder from src.gui.plotter import PlotWidget from src.controller.controller import Controller from src.utils.json_tools import read_json @@ -15,17 +14,13 @@ from src.utils.json_tools import read_json def main(): app = QtWidgets.QApplication(sys.argv) - operator_params = read_json("params/operator_params.json") - system_params = read_json("params/system_params.json") - monitor = DirectoryMonitor(system_params['trace_storage_path'], system_params['monitor_update_period']) + monitor = DirectoryMonitor() data_converter = DataConverter() - ideal_data_builder = idealDataBuilder(operator_params, system_params) - plot_widget_builder = PlotWidget(idealDataBuilder=ideal_data_builder) + plot_widget_builder = PlotWidget() controller = Controller() - mediator = Mediator(monitor, data_converter, plot_widget_builder, controller) - monitor.start() window = MainWindow() - + mediator = Mediator(monitor, data_converter, plot_widget_builder, controller, window) + window.push_settings() window.show() controller.signal_widgets.connect(window.show_plot_tabs) diff --git a/src/utils/base/__pycache__/base.cpython-310.pyc b/src/utils/base/__pycache__/base.cpython-310.pyc index 2766c4384d20bd998866b30e9194b18768aa25fc..a9ebe229704795cebc7b36be948db0cf2964c7b2 100644 GIT binary patch literal 11086 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 diff --git a/src/utils/base/__pycache__/base_widgets.cpython-310.pyc b/src/utils/base/__pycache__/base_widgets.cpython-310.pyc index 0d4e21d165387499500cee27b8a26ea44e9bb152..5ec790b6154f950f1ebb833305516da3c6bff7b3 100644 GIT binary patch delta 965 zcmZuw&rj4q6rMNRcDqaW2eACm;Kjh9F(L6zJctQI1rL~*)R=MI8AwUl;!HONL$U`p z;f#AXa@?~A|CjkEyy(S?zBdK3ij&Or>zkSPeeZkir}ocIGjBBN49B>qw_Ig^}n;xH%Mwn)WF)$qj1v_J3 z;F1A5g;OTDWP5A^yK%+(W^k;u4TVViX(5EIiIVDGt|#1jMrHe&Oq>92iC)$eJbz~y=nrnyO40|ck+5Y_1j;RJLG zA2H}zd}ykqTowooNmd)Dp;`lei~QO%>+R-!^m`h7O8ze^9VQ`$ zQ~&FHya=mbw_)2~D@ES9eaF^}DugLcGPOMZ5v)FQ6ft+cYBCVo7q?uWNhrf+mTtV*g g6sKz=aoTX>D3^mwJ)#f5P!$mic^g9LK*T%z51MVoX8-^I delta 328 zcmew=GD(0hpO=@50SMOXxuhqsP2`hd44J6yEauLT!kWU?!jQt2%GJyq#goDm%%I6W zae|LqGDtNtU&7&(|k7)6)>;^jU` diff --git a/src/utils/base/base.py b/src/utils/base/base.py index 1f22ba3..b0e31d0 100644 --- a/src/utils/base/base.py +++ b/src/utils/base/base.py @@ -5,7 +5,7 @@ from typing import Optional, Union import pandas as pd from PyQt5.QtCore import QThread, QObject, QTimer -from PyQt5.QtWidgets import QWidget +from PyQt5.QtWidgets import QWidget, QTabWidget from src.OptAlgorithm import OptAlgorithm import pandas as pd @@ -15,7 +15,8 @@ class BaseMediator: monitor: BaseDirectoryMonitor, converter: BaseDataConverter, plot: BasePlotWidget, - controller: BaseController): + controller: BaseController, + window: BaseMainWindow): self._monitor = monitor self._monitor.mediator = self self._converter = converter @@ -23,30 +24,28 @@ class BaseMediator: self._plot = plot self._plot.mediator = self self._controller = controller + self._window = window + self._window.mediator = self def notify(self, - source: Union[BaseDirectoryMonitor, BaseDataConverter, BasePlotWidget], - data: Union[list[str], list[pd.DataFrame], list[QWidget]]): + source: Union[BaseDirectoryMonitor, BaseDataConverter, BasePlotWidget, BaseMainWindow], + data: Union[list[str], list[pd.DataFrame], list[QWidget], list[dict]]): + ... + def push_settings (self, data: list[dict]): ... - class BaseDirectoryMonitor: update_timer = QTimer() def __init__(self, - directory_path: str, - update_time: int, mediator: Optional[BaseMediator] = None): super().__init__() + self._directory_path = None + self._update_time = None - self._directory_path = directory_path - self._update_time = update_time self._mediator = mediator - - self._files: list[str] = [] - - self._init_state() + @property def directory_path(self) -> str: @@ -75,6 +74,15 @@ class BaseDirectoryMonitor: def start(self): self.update_timer.start(self._update_time) + def stop(self): + self.update_timer.stop() + + def update_settings(self, data: list[dict]) -> None: + ... + + def force_all_dir(self): + ... + class BaseDataConverter: def __init__(self, mediator: Optional[BaseMediator] = None): self._mediator = mediator @@ -93,11 +101,9 @@ class BaseDataConverter: class BasePlotWidget: def __init__(self, - mediator: Optional[BaseMediator] = None, - idealDataBuilder: Optional[BaseIdealDataBuilder] = None): + mediator: Optional[BaseMediator] = None): super().__init__() self._mediator = mediator - self._opt = idealDataBuilder self._stages = [ "Relief", @@ -112,13 +118,6 @@ class BasePlotWidget: "Welding": [247, 183, 24, 100], "Relief": [0, 134, 88, 100] } - self._stage_ideals = { - "Closing": self._opt.get_closingDF, - "Squeeze": self._opt.get_compressionDF, - "Welding": self._opt.get_weldingDF, - "Relief": self._opt.get_openingDF - } - self._plt_channels = { "Electrode Force, N & Welding Current, kA": { "Settings": { @@ -199,7 +198,17 @@ class BasePlotWidget: ] }, } + def _initIdealBuilder(self, + idealDataBuilder: Optional[BaseIdealDataBuilder] = None, + data: list[dict] = None): + self.opt = idealDataBuilder(data) + self._stage_ideals = { + "Closing": self._opt.get_closingDF(), + "Squeeze": self._opt.get_compressionDF(), + "Welding": self._opt.get_weldingDF(end_time=data[0]['time_wielding']), + "Relief": self._opt.get_openingDF() + } @property def mediator(self) -> BaseMediator: return self._mediator @@ -207,10 +216,20 @@ class BasePlotWidget: @mediator.setter def mediator(self, mediator: BaseMediator) -> None: self._mediator = mediator + + @property + def opt(self) -> BaseIdealDataBuilder: + return self._opt + + @opt.setter + def opt(self, opt: BaseIdealDataBuilder): + self._opt = opt def build(self, data: list[pd.DataFrame]) -> list[QWidget]: ... + def update_settings(self, data: list[dict]) -> None: + ... class BaseController(QObject): @@ -218,8 +237,13 @@ class BaseController(QObject): ... + # FIXME: WeldingDF показывает только 1 секунду class BaseIdealDataBuilder(OptAlgorithm): + def __init__(self, data: list[dict]): + operator_params, system_params = data + self.mul = system_params['time_capture'] + super().__init__(operator_params, system_params) def _get_data(self, end_timestamp:float, func:function) -> pd.DataFrame: data = [] @@ -230,26 +254,74 @@ class BaseIdealDataBuilder(OptAlgorithm): return pd.DataFrame(data) def get_closingDF(self) -> pd.DataFrame: - return self._get_data(self.Ts['tclose'], self.calcPhaseClose) + ... def get_compressionDF(self) -> pd.DataFrame: - return self._get_data(self.Ts['tgrow'], self.calcPhaseGrow) + ... def get_openingDF(self) -> pd.DataFrame: - return self._get_data(self.getMarkOpen(), self.calcPhaseOpen) + ... def get_tmovementDF(self) -> pd.DataFrame: - return self._get_data(self.Ts['tmovement'], self.calcPhaseMovement) + ... - def get_weldingDF(self) -> pd.DataFrame: - data = [] - X1, X2, V1, V2, F = self.calcPhaseGrow(self.Ts['tgrow']) - data.append({"time":0, "Posicion FE":X1,"Posicion ME":X2, "Rotor Speed FE":V1, "Rotor Speed ME":V2, "Force":F}) - data.append({"time":1, "Posicion FE":X1,"Posicion ME":X2, "Rotor Speed FE":V1, "Rotor Speed ME":V2, "Force":F}) - return pd.DataFrame(data) + def get_weldingDF(self, end_time: float) -> pd.DataFrame: + ... def get_ideal_timings(self) -> list[float, float, float, float]: - data = self.Ts - ideal_timings = [data['tclose'], data['tgrow'], self.getMarkOpen(), data["tmovement"]] - return ideal_timings + ... + + def update_settings(self, data: list[dict]) -> None: + ... +class BaseMainWindow(QWidget): + def __init__(self, + mediator: Optional[BaseMediator] = None): + super().__init__() + self._mediator = mediator + + @property + def mediator(self) -> BaseMediator: + return self._mediator + + @mediator.setter + def mediator(self, mediator: BaseMediator) -> None: + self._mediator = mediator + + def set_style(self, object: Union[QTabWidget, QWidget]) -> None: + object.setStyleSheet(""" + QWidget { + background-color: #0D1117; + font-family: "Segoe UI", sans-serif; + font-size: 14px; + } + QMessageBox { + background-color: #161B22; + font-family: "Segoe UI", sans-serif; + font-size: 14px; + } + QPushButton { + background-color: #FFCC00; + color: #0D1117; + padding: 12px 25px; + border: 2px solid #E6B800; + border-radius: 8px; + font-family: "Segoe UI", sans-serif; + font-size: 16px; + font-weight: bold; + } + QPushButton:hover:!disabled { + background-color: #FFD700; + } + QPushButton:disabled { + background-color: #555555; + color: #cccccc; + border: none; + } + QLabel { + color: #ffffff; + font-size: 16px; + font-weight: bold; + font-family: "Segoe UI", sans-serif; + } + """) \ No newline at end of file diff --git a/src/utils/base/base_widgets.py b/src/utils/base/base_widgets.py deleted file mode 100644 index 5faf97d..0000000 --- a/src/utils/base/base_widgets.py +++ /dev/null @@ -1,47 +0,0 @@ -from __future__ import annotations - -import os -from typing import Optional, Union - -import pandas as pd -from PyQt5.QtWidgets import QTabWidget, QWidget, QVBoxLayout - -class BaseMainWindow(QWidget): - - def set_style(self, object: Union[QTabWidget, QWidget]) -> None: - object.setStyleSheet(""" - QWidget { - background-color: #0D1117; - font-family: "Segoe UI", sans-serif; - font-size: 14px; - } - QMessageBox { - background-color: #161B22; - font-family: "Segoe UI", sans-serif; - font-size: 14px; - } - QPushButton { - background-color: #FFCC00; - color: #0D1117; - padding: 12px 25px; - border: 2px solid #E6B800; - border-radius: 8px; - font-family: "Segoe UI", sans-serif; - font-size: 16px; - font-weight: bold; - } - QPushButton:hover:!disabled { - background-color: #FFD700; - } - QPushButton:disabled { - background-color: #555555; - color: #cccccc; - border: none; - } - QLabel { - color: #ffffff; - font-size: 16px; - font-weight: bold; - font-family: "Segoe UI", sans-serif; - } - """) \ No newline at end of file From 67e4a9ea7071a9b0b04cb8cbaca192f86fd3d967 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 26 Nov 2024 18:16:55 +0300 Subject: [PATCH 06/13] =?UTF-8?q?dev:=20=D0=BF=D0=B5=D1=80=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=20=D0=B3=D1=80=D0=B0=D1=84?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=BF=D1=80=D0=B8=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8=20=D0=BD=D0=B0=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=B5=D0=BA=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=81=D0=B5=D0=BD=D0=B0=20=D0=B2=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=BB=D0=BB=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/controller.py | 3 +++ src/controller/mediator.py | 6 +++--- src/gui/mainGui.py | 2 +- src/main.py | 1 + src/utils/base/base.py | 37 +++++++++++++++++++++++++----------- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/controller/controller.py b/src/controller/controller.py index bafe0ff..9f5851c 100644 --- a/src/controller/controller.py +++ b/src/controller/controller.py @@ -10,3 +10,6 @@ class Controller(BaseController): def send_widgets(self, widgets: list[QWidget]) -> None: self.signal_widgets.emit(widgets) + + def push_settings(self, settings: list[dict]) -> None: + self._mediator.push_settings(settings) diff --git a/src/controller/mediator.py b/src/controller/mediator.py index 95a79bb..b32edd0 100644 --- a/src/controller/mediator.py +++ b/src/controller/mediator.py @@ -20,9 +20,9 @@ class Mediator(BaseMediator): if issubclass(source.__class__, BasePlotWidget): self._controller.send_widgets(data) - def push_settings(self, data: list[dict]): - self._monitor.update_settings(data) - self._plot.update_settings(data) + def push_settings(self, settings: list[dict]): + self._monitor.update_settings(settings) + self._plot.update_settings(settings) self._monitor.force_all_dir() diff --git a/src/gui/mainGui.py b/src/gui/mainGui.py index ca624df..e425638 100644 --- a/src/gui/mainGui.py +++ b/src/gui/mainGui.py @@ -47,7 +47,7 @@ class MainWindow(BaseMainWindow): self.tabWidget.clear() operator_params = self.operSettings.getParams() system_params = self.sysSettings.getParams() - self._mediator.push_settings(data=[operator_params, system_params]) + self._controller.push_settings([operator_params, system_params]) diff --git a/src/main.py b/src/main.py index 1200be0..1527801 100644 --- a/src/main.py +++ b/src/main.py @@ -24,6 +24,7 @@ def main(): window.show() controller.signal_widgets.connect(window.show_plot_tabs) + controller.signal_settings.connect(mediator.push_settings) sys.exit(app.exec_()) diff --git a/src/utils/base/base.py b/src/utils/base/base.py index b0e31d0..054bb53 100644 --- a/src/utils/base/base.py +++ b/src/utils/base/base.py @@ -15,8 +15,7 @@ class BaseMediator: monitor: BaseDirectoryMonitor, converter: BaseDataConverter, plot: BasePlotWidget, - controller: BaseController, - window: BaseMainWindow): + controller: BaseController): self._monitor = monitor self._monitor.mediator = self self._converter = converter @@ -24,8 +23,7 @@ class BaseMediator: self._plot = plot self._plot.mediator = self self._controller = controller - self._window = window - self._window.mediator = self + self._controller.mediator = self def notify(self, source: Union[BaseDirectoryMonitor, BaseDataConverter, BasePlotWidget, BaseMainWindow], @@ -232,10 +230,27 @@ class BasePlotWidget: ... class BaseController(QObject): + def __init__(self, + window: Optional[BaseMainWindow] = None, + mediator: Optional[BaseMediator] = None): + super().__init__() + self._mediator = mediator + self._window = window + self._window.controller = self + + @property + def mediator(self) -> BaseMediator: + return self._mediator + + @mediator.setter + def mediator(self, mediator: BaseMediator) -> None: + self._mediator = mediator def send_widgets(self, widgets: list[QWidget]) -> None: ... + def push_settings(self, settings: list[dict]) -> None: + ... # FIXME: WeldingDF показывает только 1 секунду @@ -276,17 +291,17 @@ class BaseIdealDataBuilder(OptAlgorithm): class BaseMainWindow(QWidget): def __init__(self, - mediator: Optional[BaseMediator] = None): + controller: Optional[BaseController] = None): super().__init__() - self._mediator = mediator + self._controller = controller @property - def mediator(self) -> BaseMediator: - return self._mediator + def controller(self) -> BaseController: + return self._controller - @mediator.setter - def mediator(self, mediator: BaseMediator) -> None: - self._mediator = mediator + @controller.setter + def controller(self, controller: BaseController) -> None: + self._controller = controller def set_style(self, object: Union[QTabWidget, QWidget]) -> None: object.setStyleSheet(""" From 056d9fedb8aef7bb650149f8a5ed78ef77952506 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 26 Nov 2024 18:28:05 +0300 Subject: [PATCH 07/13] =?UTF-8?q?fix:=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B2=D0=B7=D0=B0=D0=B8=D0=BC=D0=BE=D1=81?= =?UTF-8?q?=D0=B2=D1=8F=D0=B7=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/__pycache__/main.cpython-310.pyc | Bin 1113 -> 1146 bytes .../__pycache__/controller.cpython-310.pyc | Bin 698 -> 894 bytes .../__pycache__/mediator.cpython-310.pyc | Bin 1227 -> 1237 bytes .../__pycache__/monitor.cpython-310.pyc | Bin 2132 -> 2132 bytes src/controller/controller.py | 3 ++- src/gui/__pycache__/mainGui.cpython-310.pyc | Bin 2498 -> 2623 bytes src/gui/mainGui.py | 7 +++++-- src/main.py | 7 +++---- .../base/__pycache__/base.cpython-310.pyc | Bin 11086 -> 11271 bytes src/utils/base/base.py | 16 +--------------- 10 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/__pycache__/main.cpython-310.pyc b/src/__pycache__/main.cpython-310.pyc index e3bc4809541b8c0ce5404d3dce6c972519110706..e844a7e807a5cea455e0d40f7ff16170fb5d5dbe 100644 GIT binary patch delta 209 zcmcb~@r#2upO=@50SFGia819kkvEW$ixtRo2IAt1$r+5A;WaGHjJ2#KoHdL!Of}3v z9!o7-4eJ7~g$#@gH7r@&3wUZ+vv?OWf_Z#E9$OYan8&(+AEc&)X@Niu!vevD3?R`I zhF}IwMn6rV$+sA7C#x~($w%=QXQt;R=EN7LmXu`Xr58u>7L*oez_^oxnU={&0G-3b e$OeTRjC_nh%mgHvgqSu9GdnV}3UM*A{09JXnlS(X delta 176 zcmeyxag&2LpO=@50SK}hT+;hC@&+<;u>pC`KwO+PIfGHtvzeimwS=>Vv4*LJxrU{N zwVAb+t%h|0*FpwH1|ZE1rdhIh7Vy@vX7Md#WMn8|TEJh!us~oT1BjQx5X_*-=%*<- z`30jbA8$cvaYlS`YDr0EUV8Cl6(;@3#Y{`3#DMnkFtWj+03!zw@-Yc9Z#H3eWMmcO IVr2Ob05%3DCIA2c diff --git a/src/controller/__pycache__/controller.cpython-310.pyc b/src/controller/__pycache__/controller.cpython-310.pyc index 27d6a3a959c8e427862a1775b88636e9c7061ffc..f010284da0ad2ec506cb3aa4f3afe409a3a8a615 100644 GIT binary patch delta 418 zcmdnR`j3q_pO=@50SGofcTGP#k$0(|2auD>5XG3n5XF?roXXP77{v;u*-{u&SyI_0 z8B&;1nA2ENSW;M9SfV&m*npy(a8dRY4xlJk3Ue@nCg;RQ=3<`(fJW9ZWHBsYtYKWp z$jFew5X`W0vOc30Bk$xW#!x*Tp!{bhAR)k5CGMP`S5lOplapGcSDc!c5?`K~lAc;p ze2b$vwWK67FTHpYqhx&%2T*kpCy>x&y2W3dnVy%J6Ax2R#0?fN0vTH*2qJjl1Rs!f zi?^V(I0LSnA0!EKVwD7v-6%>lxo>gA$LA&HrpCwL;);)-{FqV63lwZcLLdU<^dgWk zw^&j#lS_((L41UrU>3;YB32;54#dSEy&Mc2OdO12Oj68~t(gJ^(A7_#!z2d)m;+z- delta 229 zcmeyzwu_ZFpO=@50SHnXT++=Z@-8*d0&y6k7*iOcm{OTjS(+K6SW_5NSyI^~8B&;1 znA2ENSW;M9Sfbcdn1dNK*(NcXixmq1HPtX=F)U!LVO+?_$dJMSl$z|zsKv-Vxq>lN zjT_A-11|&EbIGCiECjVy&6hK!yIe}RY0L`WlK&#?lG^id7aS delta 77 zcmcc0d76_qpO=@50SHW5T+(N4B;Smt$%(vugmh)-5#(P31a9Kg~F0I%E@~ diff --git a/src/controller/controller.py b/src/controller/controller.py index 9f5851c..2538061 100644 --- a/src/controller/controller.py +++ b/src/controller/controller.py @@ -7,9 +7,10 @@ from src.utils.base.base import BaseController class Controller(BaseController): signal_widgets = pyqtSignal(list) + signal_settings = pyqtSignal(list) def send_widgets(self, widgets: list[QWidget]) -> None: self.signal_widgets.emit(widgets) def push_settings(self, settings: list[dict]) -> None: - self._mediator.push_settings(settings) + self.signal_settings.emit(settings) diff --git a/src/gui/__pycache__/mainGui.cpython-310.pyc b/src/gui/__pycache__/mainGui.cpython-310.pyc index 216cde6aa43e0a694f8d6f9892327c41c8ff97f2..d656f100f87089533a0363a5ab8fdc6c37bf1616 100644 GIT binary patch delta 1231 zcmZ8gOK%)S5bo}I&(4gUWCJ$D;E*_Yi4=^Hg+L@cOt8emu@gk3y$r*4doyOdv+5pW zEwW@JTM8UkeMZ^{E?hXm5yW5M)>kgv_yb6xs#nUxGwN@uy6f>(bho3Z%A-4^6OX@bN8znu zQ`Uo`8jsr-naSQSl=!qL2Y1T>uMejBdOc`lT~$Jkf4y|%VMch=5I~SF<)q6Z%Fl5o z9O2HB9d@7WQ0{Q|B<*^<&3zu6xLqHT2O`{!<_Y&W-En!uW7v;*izg?f+u|wD;G2NQ z44;LQ6r?l!EJ)dX;*#zRkUoE8;>Y|pP277#uE#8|DWL4aa$u>?0UB~lCiDTJL2y56J@x`()SK^(O&*L)4pyQx0~!@v#FQEzqH+_|Zn9|Dd;DOpT}ZheDb# z&&xsCEf8CQvFN8+97pV&vUDF~>j36Eh zp3(n0ix=nM%=lF?s`nfDJSbDRfYJ;=Td%l(UBOySuzk1WebJcK_J%C^CsUu7&~gc3 zQFpx8-@}0NWwdV%tGdY#ran$nd}-W1_?^mPGIg&$$gM5ds0ICl_sw-21LJ=zM)`+p z#_Lt0kR2v1Syrr^4v~H(Mq5%Sb@OX6Xs+nb{Css4B6J-23TxJx+f+b?yGyb5=~PM`s$kI!CH*nS%;-o^^d{Q2NNG=fb|*P zGADP4v@rv@h~d@{EU5@uxmCzwPg!OXZ%Mud0IcWqbK&JnPp7t=UW0QL0>l*Gwl2aK zW~K?4T!8(}&aD1ETsp$ZlmP;cfxSxOR;6krvX#pS7)-u_fc4wlHi=2|yjK-U^+Z+W z`4cUeM>{(k5lFZc))ErN+=o8R9>(!p6h@)@PVAm_BpPgXGKs&7yb56aW;BGxNu+1I zt08mf@1t9w%V^;SmTbd4LB_TR$(Zo%y_)Y=;syoHj(b89 Mny`e<(uB6z{{p-Uj{pDw delta 1192 zcmZ`(&2JPp6u0MlW@onKgEUZ3TOchfq$L8vsZ@NFMk+MjO%F&bRn}zfY$l!TMz*(6 zP(%*digG|A@;?xcT&o@{RpP)u(3_9^AC>x^(-st|Gn${@v){+h&(HJ6?CY84s3;Dvlr5?epK;+(5gkP*VTZ{ zyQLD}meuf4HRPk6!?zdr1B?ofS_2TIM>*+vPsuvvlzWq;=ksYE@@NwD0!R^xXfr-T zxX*+2fG0eK`GjY@F(JK_=e&S11CJ*E09G0xo#Im<G<%e4uB>Hjtnh~h`F+mS-4`#*`HzG!}n*y2@)(DLOp1`05RoB>hJBAnRgDVY1* z+>ckUIwvZp{>Rc5+heuCl+d~w4%8L%CSJ<0HuvCDH%yo;tZqhobk7@joIZym1B} zjN&^-AAj_&E!%9o4H<=GT2_OB!1A31+m%++yiFGNu{qoU+n}zLmbeSKfPi7;4Fs%< zW8n&73&sZ?LoHDm7;aSrWV$HX8ZBZaOB$!V6%r%9RwSupKOTwQ53q({g;k(WWU zVQ06imt1z6JGtG}_eN4k*8ww1_S<7!)vCP)*WQ5)!Lj!tt_;Ri``^QWM#KMsj9}Ge gdXJzh9ul<47h5AfuEpG!cvIcY$Vu+y6yI6zZ%e2OkpKVy diff --git a/src/gui/mainGui.py b/src/gui/mainGui.py index e425638..f379c4f 100644 --- a/src/gui/mainGui.py +++ b/src/gui/mainGui.py @@ -1,13 +1,16 @@ from datetime import datetime as dt +from typing import Optional from PyQt5 import QtWidgets from PyQt5.QtCore import Qt -from src.utils.base.base import BaseMainWindow +from src.utils.base.base import BaseMainWindow, BaseController from src.gui.settings_window import settingsWindow class MainWindow(BaseMainWindow): - def __init__(self): + def __init__(self, + controller: Optional[BaseController] = None): super().__init__() + self._controller = controller self.initUI() self.set_style(self) self.settings_button.clicked.connect(self._show_settings) diff --git a/src/main.py b/src/main.py index 1527801..5a0228c 100644 --- a/src/main.py +++ b/src/main.py @@ -9,7 +9,6 @@ from src.controller.mediator import Mediator from src.controller.converter import DataConverter from src.gui.plotter import PlotWidget from src.controller.controller import Controller -from src.utils.json_tools import read_json def main(): @@ -18,14 +17,14 @@ def main(): data_converter = DataConverter() plot_widget_builder = PlotWidget() controller = Controller() - window = MainWindow() - mediator = Mediator(monitor, data_converter, plot_widget_builder, controller, window) - window.push_settings() + window = MainWindow(controller) + mediator = Mediator(monitor, data_converter, plot_widget_builder, controller) window.show() controller.signal_widgets.connect(window.show_plot_tabs) controller.signal_settings.connect(mediator.push_settings) + window.push_settings() sys.exit(app.exec_()) diff --git a/src/utils/base/__pycache__/base.cpython-310.pyc b/src/utils/base/__pycache__/base.cpython-310.pyc index a9ebe229704795cebc7b36be948db0cf2964c7b2..3c45168424a855997e6cb2d4e58044b17fa24ec7 100644 GIT binary patch delta 4060 zcma)9TWlO>72esK_r7a;ZSUIN_1J62o&-B?V(L1isc9~~gg7bbB^a7v8WOsCY#@An{OC351ZChe{wJrIpGXLV^c4-i<)XU$>l|YQ?gRis1T)Pm!Vt3SOW+1fjH2tJu0_Qwfg9 zvoT%C%3sAsigzlPI7R^h$2f@ma$;r+ zZd4c)UhF2K`Ncl)`&)Q4vnfA7JlV4ikiH#seZjlZL$1`_W}8&&6VnjPfM_5+kAR|d zjB6*dF6wj^>`UTa$d*93UC7S~qX=|TjzEkC2vk*Yj7McT*`N1{HxCV;N1Vlyd@cE{ zu)9flBc7GTbadtcm~h$dh%6koC!|PCEBj=*G%>r-?$V{wT#Yj@Ta+KBROL`}xy8F! z4hen%zRMuI@dM;vxL3uy*I^pEw*e(VWA<4pold8?{6!c{$(!j(Zm>9x_s@WwAVP!A zjST^J5|ko;;5Q z?zxu{)TXRt|JXcohX<}IhJ0_}+&wwCUjkv6di%jvoL(LVj~HgT`rt;TYMA1;^6cQE zi-F^JiGe>LI?vFd2g{aus#>?7su&kcd+wrXRLXW;h#hRq-X%8vgqX|n#L)h|J6X^; zeF5TbSiFqga31oVp`3ELiNytPy_ZQ%XPXNG^OoMC76P&lz%0vrZh5Z?HVeWv>o&1M z=TNi1!e&aolG{J~|9$uf|IPKdm21JQ=3iMMpm3))q4%bWhvvpKxy zDf#VTHQ_{>-wZK6iME^%{h_b0T6vufD@IgykDPaulB zEevce)LHmzFu3Dg3N^Y#j}<0DcPW1=AX6i6#?jyAwd`jjXZv=>0jMlPjJl%=w zZU^uy_yDxE_qVTUmu&koAq8Ihp@Mv7%MHQ zB>La$Icb_ox_zlu)H;vQJx2S7TV)90r@G46qxxS8U zJZZz?El7DXBs&4hADQn!k7f$=M!W>_U62<+z6Y{19R^$K;f;qYa%o~*xzhL*@VR*> zg;RB+T&X=(sTuX>Rzx2~`B(1bx?QQ)%GJ-eAG)XI?@I&n(QiYQXh=tYY3xhSfeqpfSC>p?D zx_tYd=Dc5iUB7idK-9NEIuL}YDxxmGo10t@X?z@ic)Ot!r4dJ$_DfZB66O!fn_7`? zJk)xw#rMgn2?Gohnhz`o-0A5TbJimFzAK%%X9go1bhQB^7m5*iR95{Qf7FX#iD-eqA+`Ib~Cw)dKP@&%R>|VSTZ*YKu~_Xo`gv-Mv5yI6liPE{O;!5;1@{Ks!K! zz@{S7@^7B=yKoW+1l53AdE_bYpARO%mnNWjMHld1fb7;OlSDVYI)T-aU07Pr$me{g zC;P#$ExYM)Wt)jb%WKw)x@FpSVRhLWkiYW{sUi89Z%AYFLAEvul$w&JvAl25?E-1)tcY& zTWe)gh#q-2@Mw-bPZ42Lby{_Ov6#0kU9UPXaJwdlTk;$*O%`7x4cvS7x;J*+I@Ozdwq@dQ+KsM!wy8 zQccQxt-B8*9^yEGty(y7zmOBw3#$cNw`_9q37HG&M>!c@CsO0Mpw!rTVec3w@g%8! zMt&5U8)0#ec!Cb74eV06SvbT~L_RA|gmZyPJ>5wqF01bn;(pRB=; z5l;NfgVNvhxw63B)06J0>vi3!)-HxNaH0VW1GE4jl3eUguq;Z{AojXAj597K&MEA3 z0*D8-&uP$*4-T?;2G|)eL@QmiXp--hPT~?e02XdnKYDeqyb%3v!1Y<)N%am*f&Spy zLo?3Hqp^MJA$ch|FuGmcg3EOR8k&^r0?v=f_hWtPNnCY!3I`9q3Wi+*+cW_Ce~e_g zd?p$S;1pQu?{y+Hvae7Sb?WQvMrfZeWX~6jWz!xjm2GhY zr8hnW9<~FKrcP(yA>B;lUvNGx@1>^pH`H9Sk>$UOg-lMK?>sd6a2amgzq=AY z>8vSF%`-boHNi=F8T9HbsTOW!2Hhe$dBRRG?sK_sLyimj>%h)|Ez-2AZ-P#xJ*l{p zjBA_qeFGGpE?)vxje2#Q>>|RF{ASma6Nsy+EYSY6;4y-R-w5!=)iuok z6=+xkSRp{mqhI7#mrXG#KkFTcvyN|p`X)eDj%KpqYOK5EeCErI)ieRl8Xmmj%c7`+ z|-Pf@c^bu0FP= zp~ms?%|hSwhac=I`!(*Jw;@u`=(N(RL@V!l(HsQ()AG!4W{2-Ti~k5Z+>t~WO{|8Q z!I_~USvw=&!RwBbv4f}`bhi~JB&c{i@xA}`_^}5>)ON4?3#`)#>H5-|y(Uar*F4ZS jBOe)gBh51h8fyGv54+{3BU-dGb|4m4HsbzxFfsT)c+ BaseMediator: - return self._mediator - - @mediator.setter - def mediator(self, mediator: BaseMediator) -> None: - self._mediator = mediator def send_widgets(self, widgets: list[QWidget]) -> None: ... @@ -294,6 +279,7 @@ class BaseMainWindow(QWidget): controller: Optional[BaseController] = None): super().__init__() self._controller = controller + ... @property def controller(self) -> BaseController: From 384d52309f322ad266282adb994a03631810b1e7 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Dec 2024 11:04:15 +0300 Subject: [PATCH 08/13] =?UTF-8?q?dev:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B8=D0=B7?= =?UTF-8?q?=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=B2=D0=B0?= =?UTF-8?q?=D1=80=D0=BE=D1=87=D0=BD=D0=BE=D0=B9=20=D1=82=D0=BE=D1=87=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/__pycache__/main.cpython-310.pyc | Bin 1146 -> 1092 bytes src/gui/__pycache__/plotter.cpython-310.pyc | Bin 7176 -> 7658 bytes src/gui/plotter.py | 72 ++++++++++-------- src/main.py | 2 - .../base/__pycache__/base.cpython-310.pyc | Bin 11271 -> 11308 bytes src/utils/base/base.py | 19 +++-- 6 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/__pycache__/main.cpython-310.pyc b/src/__pycache__/main.cpython-310.pyc index e844a7e807a5cea455e0d40f7ff16170fb5d5dbe..03f720e8b37eadff800b62f68b03dc11fad279ff 100644 GIT binary patch delta 184 zcmeyxafE|6pO=@50SNxQa7|w_kynL3qzDps&EQVHdB#ns!%fnBSQ*f zFc@p{PCQk%*_W}Ck&$=ubtW4|zR4oYibDKAQ*Lp@$LA(y=EcWriWG58c4s~kR0I>x zOUzA;k1yf{Dnlapz`AU5^HWN5QtcRlykZ$3!NI`8$ic|N$ioE0P{_f|A;iVV@*e=E CqbI5W delta 239 zcmX@Y@r#2upO=@50SFGia8183kyn;+)-GbsuQ z0L{O}5g(tMn3)$JuPIi)IYlrnd5O8H y@$p4`ATb2N4>r&yH$SB`C)JJ-$Salu5*!RXj2w(Sj66(042K-d970@-EdK${_Bf#c diff --git a/src/gui/__pycache__/plotter.cpython-310.pyc b/src/gui/__pycache__/plotter.cpython-310.pyc index 7fb0c8ff774c18b0eccefde41ddee9a08cee7464..9fb8f4cbb1ecd9793abed92b9b2b8375aecb70a4 100644 GIT binary patch literal 7658 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 a_ZcKYvMn3`lG*s>85{u5)5-Hn+4_Gvv*A+! literal 7176 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 pd.DataFrame: return self._get_data(self.Ts['tmovement'], self.calcPhaseMovement) - def get_weldingDF(self, end_time: float) -> pd.DataFrame: + def get_weldingDF(self) -> pd.DataFrame: data = [] X1, X2, V1, V2, F = self.calcPhaseGrow(self.Ts['tgrow']) data.append({"time":0, "Posicion FE":X1,"Posicion ME":X2, "Rotor Speed FE":V1, "Rotor Speed ME":V2, "Force":F}) - data.append({"time":end_time, "Posicion FE":X1,"Posicion ME":X2, "Rotor Speed FE":V1, "Rotor Speed ME":V2, "Force":F}) + data.append({"time":self.welding_time, "Posicion FE":X1,"Posicion ME":X2, "Rotor Speed FE":V1, "Rotor Speed ME":V2, "Force":F}) return pd.DataFrame(data) def get_ideal_timings(self) -> list[float, float, float, float]: data = self.Ts - ideal_timings = [data['tclose'], data['tgrow'], self.getMarkOpen(), data["tmovement"]] + ideal_timings = [data['tclose'], data['tgrow'], self.welding_time, self.getMarkOpen()] return ideal_timings - + class ProcessStage(NamedTuple): mean_value: floating[Any] @@ -42,38 +42,41 @@ class ProcessStage(NamedTuple): class PlotWidget(BasePlotWidget): - def _create_stage_ideal(self, + def _create_curve_ideal(self, stage: str, signal: str, - times: pd.Series, - dataframe: pd.DataFrame) -> Optional[pg.LinearRegionItem]: - stage_diff = np.diff(dataframe[stage]) - start_index = np.where(stage_diff == 1)[0] - finish_index = np.where(stage_diff == -1)[0] + start_timestamp: float, + finish_timestamp: float) -> Optional[pg.PlotDataItem]: data = self._stage_ideals[stage] - if start_index.size: - start_timestamp = times[start_index[0]] - finish_timestamp = times[finish_index[0]] if finish_index.size else times[len(times) - 1] + if start_timestamp and finish_timestamp: plot = pg.PlotDataItem(x=start_timestamp+data["time"], y=data[signal["name"]], pen=signal["pen"]) return plot return None def _create_stage_region(self, stage: str, - times: pd.Series, - dataframe: pd.DataFrame) -> Optional[pg.LinearRegionItem]: - stage_diff = np.diff(dataframe[stage]) - start_index = np.where(stage_diff == 1)[0] - finish_index = np.where(stage_diff == -1)[0] + start_timestamp: float, + finish_timestamp: float) -> Optional[pg.LinearRegionItem]: - if start_index.size: - start_timestamp = times[start_index[0]] - finish_timestamp = times[finish_index[0]] if finish_index.size else times[len(times) - 1] + if start_timestamp and finish_timestamp: region = pg.LinearRegionItem([start_timestamp, finish_timestamp], movable=False) region.setBrush(pg.mkBrush(self._stage_colors[stage])) return region return None + + def _get_timestamp(self, + stage: str, + times: pd.Series, + dataframe: pd.DataFrame) -> Optional[list[float]]: + stage_diff = np.diff(dataframe[stage]) + start_index = np.where(stage_diff == 1)[0] + finish_index = np.where(stage_diff == -1)[0] + if start_index.size: + start_timestamp = times[start_index[0]] + finish_timestamp = times[finish_index[0]] if finish_index.size else times[len(times) - 1] + return start_timestamp, finish_timestamp + return None @staticmethod def _init_plot_widget(title: str) -> tuple[pg.PlotWidget, pg.LegendItem]: @@ -115,15 +118,26 @@ class PlotWidget(BasePlotWidget): settings = description["Settings"] if settings["stages"] and all([stage in dataframe_headers for stage in self._stages]): for stage in self._stages: - region = self._create_stage_region(stage, time_axis, dataframe) - for signal in description["Ideal_signals"]: - ideal_plot = self._create_stage_ideal(stage, signal ,time_axis, dataframe) - if ideal_plot: - plot_widget.addItem(ideal_plot) - + start_timestamp, finish_timestamp = self._get_timestamp(stage, time_axis, dataframe) + region = self._create_stage_region(stage, start_timestamp, finish_timestamp) if region: plot_widget.addItem(region) + for signal in description["Ideal_signals"]: + ideal_plot = self._create_curve_ideal(stage, signal, start_timestamp, finish_timestamp) + if ideal_plot: + plot_widget.addItem(ideal_plot) + + if settings["performance"] and all([stage in dataframe_headers for stage in self._stages]): + delta_timestamp = 0 + for stage in self._stages: + start_timestamp, finish_timestamp = self._get_timestamp(stage, time_axis, dataframe) + delta_timestamp += finish_timestamp - start_timestamp + + ideal_delta = self._opt.get_cycle_time() + performance = round(ideal_delta/delta_timestamp*100, 2) + performance_label = QLabel(f"Performance = {performance} %") + layout.addWidget(performance_label) if settings["zoom"]: if max(time_axis) < 5.0: @@ -170,8 +184,6 @@ class PlotWidget(BasePlotWidget): plot = plot_widget.plot(time_axis, dataframe[signal["name"]], pen=signal["pen"]) legend.addItem(plot, signal["name"]) - - layout.addWidget(plot_widget) widget.setLayout(layout) diff --git a/src/main.py b/src/main.py index 5a0228c..3d20261 100644 --- a/src/main.py +++ b/src/main.py @@ -1,7 +1,5 @@ import sys from PyQt5 import QtWidgets -import json -from os import path from src.gui.mainGui import MainWindow from src.controller.monitor import DirectoryMonitor diff --git a/src/utils/base/__pycache__/base.cpython-310.pyc b/src/utils/base/__pycache__/base.cpython-310.pyc index 3c45168424a855997e6cb2d4e58044b17fa24ec7..6d8394a08f4936c2c0a4b2d98bb1f0a00627e2c9 100644 GIT binary patch delta 1111 zcmZXTU5Fc16vyY>nM`K0lWaEMnPijAW-HAGYH8Vu`lNyntuB>XC_xD8-q|$E&ZgcZ zEse9b(#3rcTg2fr`pWpeo zckchdtRA{>DAEdtLkc~Y55L@aZu`Z^_fhx_e~msLF!<2AicgL14g`I2MyvnQN29m% zs;Bi@EyvT_o!N%n_J)txV!kDu*`+xf-;G_;n{=jFz`gOig?9);Ob1$q4)Qe~uptHv zw7*yoUrFSuKe4e#F=hW|0bl=QrXiz;+I^ONR7Xsd)t}9)cq!3>Jy=PWa(!)}xXJ?b z0|SM_y5=f%oht{F3Y)>x$)?_ucPZe&h+{kzi+)34+mx454b=bxr&9uM;Mr6IZelb& z3*VtgH{mwkN-x13+?T1t4|qQF^wv3V;*Xh&FpulmD{v1FTQ1zkJJu@PMJM-6BfqN5 z16R4WV%AhX#)rANqSZ8B;9(vi3J{I(D3MMy%40-9qBu_w8AM5*A{ydFp5a-d5Fh6j z&k+r;DwM~ayFi`w~s53RQ z({$|m-0YD~SJ<_%A02Dji@dqisA!(*bQeAI*j8MZRZ*4W%aK$xk&#>=sg2-TewXA`sFyznn+{Stk``L!G~4pi>ydcV{u}PwoQ9;gKT?S zyC{_1#jhTO1-}|y#Rq*TeG+^Z@j>Z>LO?-95T%NWsOYYqx$!~pUgkf)ne#t$XU?6g z+o!jCs~(Sw(R2LS#`0e)=Dbh*@DktnHz;jqIQDh)I{j!z-su}1k9@qTj#aBeO}%Cf zluI={7r3tPqXo^e z*3yE*Y?j;HRvH|bQzhPCa61LsGcaP+%~DQjDns=_{5!G9^;Q-`Co$$9B_hyXCp0Z7 zgQz5b4jz?wTuPFp2^Dh&Hz$9B4`?Ur!0<*_20K%mK*8OqQP7?7yVN#l!!2E_xH&!( z?}c%kiv+bP%6C)zEcnQq!HI4U-t~s@gc`xgXbb|BkrMS0F<_O7wUTAgpRAe7DJ!R& z&Nhw_xAt;E(i$lzWt@M*`oGe9(K%y)uxoxHJEp-UdEIb#j|;MRpl3B) zz|%b|^-I!w8E^IU!WCM58C__`Ix&@xK?D2pYvB}* pd.DataFrame: @@ -265,14 +269,15 @@ class BaseIdealDataBuilder(OptAlgorithm): def get_tmovementDF(self) -> pd.DataFrame: ... - def get_weldingDF(self, end_time: float) -> pd.DataFrame: + def get_weldingDF(self) -> pd.DataFrame: ... def get_ideal_timings(self) -> list[float, float, float, float]: ... - def update_settings(self, data: list[dict]) -> None: - ... + def get_cycle_time(self) -> float: + result = sum(self.get_ideal_timings()) + return result class BaseMainWindow(QWidget): def __init__(self, From 84d3e3a88d8f908052d1fc03fa1bd1787d28eb53 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Dec 2024 11:21:22 +0300 Subject: [PATCH 09/13] =?UTF-8?q?dev:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BB=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B2=D0=B0=20=D0=BE=D1=82=D1=80=D0=BA=D1=8B?= =?UTF-8?q?=D1=82=D1=8B=D1=85=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/__pycache__/main.cpython-310.pyc | Bin 1092 -> 1045 bytes src/gui/__pycache__/mainGui.cpython-310.pyc | Bin 2623 -> 2986 bytes src/gui/__pycache__/plotter.cpython-310.pyc | Bin 7658 -> 7631 bytes src/gui/mainGui.py | 10 ++++++++++ 4 files changed, 10 insertions(+) diff --git a/src/__pycache__/main.cpython-310.pyc b/src/__pycache__/main.cpython-310.pyc index 03f720e8b37eadff800b62f68b03dc11fad279ff..3c948a818978b51d6522ad445ddeebd8d5aa0134 100644 GIT binary patch delta 340 zcmYj~KTE_g9EOu7ZPQ-=sKY6Tr#K!$C!H*=PJ-f=B^)*!#pEivc2Jx=zd#8tehUZJ zo7~+GzlEcVNkBA^hv)b5!uw91N!p}o49xqg&u5Q)I)?ZC;fN!FB&HaG3RGD5GN6HT zUxboS;ye(MjA`sV6a$&i#5obE%xGpjs^TX=bG}gxZaj6u^Cd7TymEh%^sC|P=N24c zGp_=R(1KVX3ttoO4JLZ!m4@Hm!BJ-7HDOFn>p5eSO%<7d`WJVX?XmK#=L>aR%(}X; zm9wr^NHeqxv3@{f=<64>w{55Xdbgr!Tdq{7KhS>Z#(!7lQ^^@qiRu4CYR)w&Wm9#6 PpF(pjb_@v61s?tY6huj| delta 462 zcmZ9Hze)o^5XNurPi`-{&6#KfgApu)kj^gH1v@cV2-}u zFJNJ5=Tlr`tKcJ8xVs_|7v|&l%`(F`_vjU2j&a>m@9TXudtBlk+%5OI3!n~h5-V}2 z%RJ(NrP!r4<`dtrM-dB1V7Nx>tU(%veHt=Muwg`-EFzKNfUdC?X(_HJja!Sf)Ac00 zw8bcG-&m>(C#L%NLuWba^q~sI@-$0ksVtOnuO{;R>7@f*PyGvD3(^v3akbRSPk07g zKG;KOmT&g%S)|$(ieom(@;L5q2z@B=j<3gZU)Y-6i-PBs%?sgZ8x>+Yn9Z|+o;aLm zW--~+-6_wd;FP9fz<8cXE`(Q(ogUOm?(8gdpw;*l8gXsd#-L@xdYJ*RCb diff --git a/src/gui/__pycache__/mainGui.cpython-310.pyc b/src/gui/__pycache__/mainGui.cpython-310.pyc index d656f100f87089533a0363a5ab8fdc6c37bf1616..2fcd01637e963826840726487b51332de78fc893 100644 GIT binary patch delta 889 zcmYLH-A@xi5Z}4(^*;JZX>9|@M=*wJKr{g&7|;OG2O;4jAzosdmOblX>B-(zl$4Mt ziEqB_6EEhP7)*?B`tF;5#3jD)=073MUPX2@v%i_0`Q6UU{m6eQrrlJ^B)GoruGBvp zoit?MqGb~c7_k%s*cCAdMJS4CxP7b0GAw&ctrRP=9+pFtX1#WXsSKV`mS+X@WZx4? ztey>0E`2+Oe&wivd_D=FL)xUGw8@SV#29n{(B4sYXrSU5mo`Re9dZb52y}V(&u1`1 zm}{cX3=%9B<#uDtE>DnbM~sZ%cj@ZpL2Bc_Gelh2KwtcnNf(8O;A zsW_l2r#ZzV)Yi5fR=52yvG$NV>~Zyt+w%FS47)Cl)v4uB-F90|KU8_OS-1I!%++{F z28>C9#LI^3SN6LkF)SpcbtJM3gq3b8IO3N&G&+RgULPtQS|4f=YD>NJ`CdRx|fu_TV6L@muCz=q$gCU44q>qJrLc^uN`rddkp8J(KcjP=F2ftRZ|&}g{h;>0-p3s!%{M_cQPF?FOMTgzkS|}p?|bj%%k1~qjG{<0THk)(9&V`0Ky!~? z1D1kiDG$LO#|4;$7_UHgKDG_pd@a(*#`c(8k2-h&^6ZgA8u_w+OfkyKE}I3<2$h%7;-d1aNPvN6rBw^S&Dap$MUEt{s>O- zWD1q+$TMWRv$!Nz!z6HX{&gN-$o86Rdp>~$^^zvu)VEGv@X@Y^s~%zx>mFM8SuZCuL>1#)97-^UTF-?lR6>jC RnhVM5CB|`|zKCM#(?1s`X?6er diff --git a/src/gui/__pycache__/plotter.cpython-310.pyc b/src/gui/__pycache__/plotter.cpython-310.pyc index 9fb8f4cbb1ecd9793abed92b9b2b8375aecb70a4..296bd55c5779b54ebd6fd352236cc07391319e87 100644 GIT binary patch delta 685 zcmYk4O=uHA6vyXnJ~rKC)BTwJN}8r1en3@FMARZh%tg>cQK%Mra%gEP*2dLfnWe%C z@uCzSwn$YrikFCox`Njh#gpJoq-RgwJb3fq>^6kX;XVHE&F_5-^Lyg^gu0}v3K8eq z!j<`ZTk7co9Eux-X$g+SFBA*lZ2X}(1JH<7^)kRzJX8J!a04f`X*h=)+HrV@U$u7! zd%oO(IbcI9|ETa-Y8DzKgb-RirUcrap4D+(A6s1xgjAz)mjt>$%yq6+2`f^jgF4^;}Lt64?YJTN)3e~ZK$zVu dTe#`BR`7!C=1z*hQH)1s;Tr0-ADIfx{|6?Nv4j8s delta 711 zcmZ9KO=uHA6vyXnJ~rKC)BTwJm?Ui~A|l25aS*hJQmi1N2lY@46b}xmjab`sp+#ry zVGAjOB8=8z6*h_>h(fa7#A}6Ky!FttUc{3JPad4zh9J&i-n{pJzc=p<^L6~kxOzub z6(rX6o0n#Pb<|TiI2=vorX?7QUMLp8nW&qu0i26e^&-HPs8;+2P~#KYG+f}%v@uxc z+uFNBT~BU79q0hfuI1LHMs5lP5J0m_6<^!;XDq&^s?1n=XW;2^& zj9j#DX#peVcy{Q{B5J*YHcAJUB7*Z>>IGrbB`kd!HYs!?fC~m1k-% zv&0)_HM7CwMwLG@NA>08mE~An#7qiD_>Q>+E4+@M!W#dBKf)85WkI+O diff --git a/src/gui/mainGui.py b/src/gui/mainGui.py index f379c4f..8df989a 100644 --- a/src/gui/mainGui.py +++ b/src/gui/mainGui.py @@ -19,6 +19,8 @@ class MainWindow(BaseMainWindow): def initUI(self) -> None: self.tabWidget = QtWidgets.QTabWidget() + self.tabWidget.setTabsClosable(True) + self.tabWidget.tabCloseRequested.connect(self._close_tab) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.tabWidget) self.settings_button = QtWidgets.QPushButton("Show settings") @@ -35,6 +37,12 @@ class MainWindow(BaseMainWindow): self.tabWidget.addTab(tab, "SF_trace_" + dt.now().strftime('%Y_%m_%d-%H_%M_%S')) self.tabWidget.setCurrentWidget(tab) + tab_count = self.tabWidget.count() + if tab_count > 10: + for i in range(0, tab_count-2): + self._close_tab(i) + + def keyPressEvent(self, a0): if a0.key() == Qt.Key_F5: self.clear() @@ -52,6 +60,8 @@ class MainWindow(BaseMainWindow): system_params = self.sysSettings.getParams() self._controller.push_settings([operator_params, system_params]) + def _close_tab(self, index:int) -> None: + self.tabWidget.removeTab(index) From 71c82855833552f136960905a48fa36aed26b260 Mon Sep 17 00:00:00 2001 From: ermolaev_p Date: Mon, 2 Dec 2024 12:46:10 +0300 Subject: [PATCH 10/13] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20=D1=81=D0=B8=D0=B3=D0=BD=D0=B0=D0=BB=20Onc?= =?UTF-8?q?omming,=20=D0=B1=D0=B5=D0=B7=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- params/system_params.json | 17 +++++++++-------- src/utils/diagram_parser.py | 5 ++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/params/system_params.json b/params/system_params.json index 017e7fb..5749167 100644 --- a/params/system_params.json +++ b/params/system_params.json @@ -1,11 +1,11 @@ { "a_max_1": 5.41, - "v_max_1": 0.108, + "v_max_1": 0.278, "a_max_2": 35.81, - "v_max_2": 0.678, - "mass_1": 257, + "v_max_2": 0.7, + "mass_1": 270, "mass_2": 1, - "k_hardness_1": 1759291, + "k_hardness_1": 2148570, "k_hardness_2": 0, "torque_max_1": 20, "torque_max_2": 0, @@ -13,11 +13,12 @@ "transmission_ratio_2": 1, "position_start_1": 0.08, "position_start_2": 0.08, - "k_prop": 0.05, - "time_capture": 100000, + "k_prop": 0.075, + "time_capture": 10, "UML_time_scaler": 1000, "Closure_signal": "Closing", "Squeeze_signal": "Squeeze", "Welding_signal": "Welding", - "Release_signal": "Relief" -} + "Release_signal": "Relief", + "Oncomming_signal": "Oncomming" +} \ No newline at end of file diff --git a/src/utils/diagram_parser.py b/src/utils/diagram_parser.py index 5c7451d..c72559a 100644 --- a/src/utils/diagram_parser.py +++ b/src/utils/diagram_parser.py @@ -7,7 +7,8 @@ class DiagramParser: self.signals = [system_config["Closure_signal"], system_config["Squeeze_signal"], system_config["Welding_signal"], - system_config["Release_signal"]] + system_config["Release_signal"], + system_config["Oncomming_signal"]] self.boolDict = {} self.floatDict = {} @@ -22,6 +23,7 @@ class DiagramParser: for signalName in self.data.columns: if type (self.data[signalName].iloc[0]) == np.bool: + print("!", signalName) self.boolDict[signalName] = self._getBoolChanges(signalName) for signalName in self.data.columns: @@ -33,6 +35,7 @@ class DiagramParser: elif key == self.signals[1]: name = "compression" elif key == self.signals[2]: name = "welding" elif key == self.signals[3]: name = "opening" + elif key == self.signals[4]: name = "oncomming" self.timingsDict[name] = [] len_items = len(items) From 918663fa4490c5291a4a7c5e047dea16d18a5b76 Mon Sep 17 00:00:00 2001 From: ermolaev_p Date: Mon, 2 Dec 2024 12:47:47 +0300 Subject: [PATCH 11/13] =?UTF-8?q?chore:=20=D0=A3=D0=B1=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=20=D0=BE=D1=82=D0=BB=D0=B0=D0=B4=D0=BE=D1=87=D0=BD=D1=8B=D0=B9?= =?UTF-8?q?=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/diagram_parser.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/diagram_parser.py b/src/utils/diagram_parser.py index c72559a..aceb9ce 100644 --- a/src/utils/diagram_parser.py +++ b/src/utils/diagram_parser.py @@ -23,7 +23,6 @@ class DiagramParser: for signalName in self.data.columns: if type (self.data[signalName].iloc[0]) == np.bool: - print("!", signalName) self.boolDict[signalName] = self._getBoolChanges(signalName) for signalName in self.data.columns: From dcb05aad768f7fb7b7dbdfed35e33fb017cdddfa Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Dec 2024 12:04:05 +0300 Subject: [PATCH 12/13] =?UTF-8?q?dev:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=82=D1=80=D0=B8=D1=81=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D1=8D=D1=82=D0=B0=D0=BF=D0=B0=20"=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D1=89=D0=B5=D0=BD=D0=B8=D0=B5"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- params/system_params.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/system_params.json b/params/system_params.json index 138c337..b34adee 100644 --- a/params/system_params.json +++ b/params/system_params.json @@ -17,6 +17,6 @@ "position_start_2": 0.08, "k_prop": 0.05, "time_capture": 100000, - "UML_time_scaler": 1000, + "UML_time_scaler": 1000 } \ No newline at end of file From 40767d813a294d50ba22ccf7419f09594abe1e32 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Dec 2024 12:09:31 +0300 Subject: [PATCH 13/13] =?UTF-8?q?dev:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=82=D1=80=D0=B8=D1=81=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D1=8D=D1=82=D0=B0=D0=BF=D0=B0=20"=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D1=89=D0=B5=D0=BD=D0=B8=D0=B5"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- params/operator_params.json | 2 +- .../ConstantCalculator.cpython-310.pyc | Bin 1172 -> 1355 bytes .../__pycache__/OptAlgorithm.cpython-310.pyc | Bin 15481 -> 15505 bytes .../OptTimeCalculator.cpython-310.pyc | Bin 7744 -> 8862 bytes src/__pycache__/main.cpython-310.pyc | Bin 1045 -> 1045 bytes .../__pycache__/controller.cpython-310.pyc | Bin 894 -> 894 bytes .../__pycache__/converter.cpython-310.pyc | Bin 1226 -> 1226 bytes .../__pycache__/mediator.cpython-310.pyc | Bin 1237 -> 1237 bytes .../__pycache__/monitor.cpython-310.pyc | Bin 2132 -> 2132 bytes src/gui/__pycache__/__init__.cpython-310.pyc | Bin 246 -> 246 bytes src/gui/__pycache__/mainGui.cpython-310.pyc | Bin 2986 -> 2991 bytes src/gui/__pycache__/plotter.cpython-310.pyc | Bin 7631 -> 7770 bytes .../settings_window.cpython-310.pyc | Bin 2526 -> 2526 bytes src/gui/plotter.py | 16 +++++++++++++--- .../diagram_parser.cpython-310.pyc | Bin 2813 -> 2877 bytes .../base/__pycache__/base.cpython-310.pyc | Bin 11308 -> 11502 bytes src/utils/base/base.py | 13 +++++++++---- 17 files changed, 23 insertions(+), 8 deletions(-) diff --git a/params/operator_params.json b/params/operator_params.json index 76d9da0..5a96d09 100644 --- a/params/operator_params.json +++ b/params/operator_params.json @@ -8,7 +8,7 @@ "dist_close_end_1": 0.005, "dist_close_end_2": 0.005, "time_wielding": 1, - "time_command": 0.06, + "time_command": 0.0, "time_robot_movement": 0.2, "object_thickness": 0.0045, "force_target": 5000, diff --git a/src/OptAlgorithm/__pycache__/ConstantCalculator.cpython-310.pyc b/src/OptAlgorithm/__pycache__/ConstantCalculator.cpython-310.pyc index 22ef9194d297bc27a5d2f6cd2f44cfc392a59d6e..0f5d90b3e7e87e4bc7fcd58e7f17358f7ac73c16 100644 GIT binary patch delta 412 zcmYjMF-yZh7`;m_H7%yb+QC62P(g}|&UL9Mxai_0N(f0TscBMkS1FicZ3kB&u0s0{ zDz)ff?GJFdtO5Uu_@xed@V)Q*-h21Bd(3|36kkzt2u{U6s*Rr&0pCinr6oeqJphLK zXn>he7egEhLlL78)yY5_qJ4C(o(UbXLqftbEflPW#KM=**@7kXaSvbREp&p);&Ff> zsdWgzpZJ8o@DDzV`|(}e<8S;Owu#1H`IL{g;(O4izydSlqqxgQV3@?cbkc5`Mqo5L z+OD=;mZJ(TRTEj)EyrZKo=6U}8#ECek0sfIwrMw+<9lT(A=Gv+g7jBG1|X5PX3HD^uVqs;Ia4OY^GITTZcn1*XE!9-Id!KxTN qh^HH+R8w@_bPY;P+jVvQ-_2!EgJP5?t5}XUNmcy|{Y{SAWbFsIfqaYr delta 247 zcmX@jHHDKmpO=@50SFFAxumCVA zpI2Oxm{(F<#0ydhCip-yEXj#E$=pCzF^J2;D8M$^oh8av79__TAD^6)SX`W(nv)YB rkE9c%z6hkghy|nxh>JOZ1P22PlNh4_%jA13jsggKAeK$mXO#f}GW9FC diff --git a/src/OptAlgorithm/__pycache__/OptAlgorithm.cpython-310.pyc b/src/OptAlgorithm/__pycache__/OptAlgorithm.cpython-310.pyc index 4983639187b0fe39fd65e4a407c890a7c463f280..a43688a22848d5696817442cd9e65855067a4c52 100644 GIT binary patch delta 2802 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 iFAq0#`EU4}__2KrPwwoI4^5uWRScP~1 diff --git a/src/__pycache__/main.cpython-310.pyc b/src/__pycache__/main.cpython-310.pyc index 3c948a818978b51d6522ad445ddeebd8d5aa0134..443fd68e2c3878e94cbeea0bf6502b6536099a2d 100644 GIT binary patch delta 19 ZcmbQrF_nWWpO=@50SHX;H*#^a001P>14RG; delta 19 ZcmbQrF_nWWpO=@50SG>4Zsg)-0RSm21O5O2 diff --git a/src/controller/__pycache__/controller.cpython-310.pyc b/src/controller/__pycache__/controller.cpython-310.pyc index f010284da0ad2ec506cb3aa4f3afe409a3a8a615..b9735763aa2b7d99d00f9a73cbd8b130df357694 100644 GIT binary patch delta 20 acmeyz_K%G_pO=@50SHX;eK&F!GXnrP{RGJX delta 20 acmeyz_K%G_pO=@50SGofciqTc%nSfO9tF4n diff --git a/src/controller/__pycache__/converter.cpython-310.pyc b/src/controller/__pycache__/converter.cpython-310.pyc index 05a99387fafeef2721b072c1d73c8874ac54e18b..2f47d791c02512d581ee0c14b47b1f9ef8d72d3c 100644 GIT binary patch delta 20 acmX@bd5V)epO=@50SHX;eK&INX8`~*N(8h3 delta 20 acmX@bd5V)epO=@50SICYTsCs=X8`~)y9AT~ diff --git a/src/controller/__pycache__/mediator.cpython-310.pyc b/src/controller/__pycache__/mediator.cpython-310.pyc index 53ed4954325a68a02111c5554c7ec7b600d9c5b6..5725fb29a5d7a912a5f697e851945fb69c06d251 100644 GIT binary patch delta 20 acmcc0d6knppO=@50SHX;eK&HSVgUd&0tD3n delta 20 acmcc0d6knppO=@50SLMuxo+e>#R330?FE+r diff --git a/src/controller/__pycache__/monitor.cpython-310.pyc b/src/controller/__pycache__/monitor.cpython-310.pyc index 5987012df5346432926013683e7f6bfd5ab97db4..77287fbf23571757ac607098c2764ed4c265d4d3 100644 GIT binary patch delta 20 acmca2a7BPSpO=@50SHX;eK&G@asU7`+5}_( delta 20 acmca2a7BPSpO=@50SL0%T{d!iasU7|w*;vG diff --git a/src/gui/__pycache__/__init__.cpython-310.pyc b/src/gui/__pycache__/__init__.cpython-310.pyc index 4d2a80231dae29a24aa945a59b19a4be71e68f62..8f86e2fa3a3a6e7cb8a0e719a989731c0358396e 100644 GIT binary patch delta 19 Zcmeyy_>GY}pO=@50SHX;eJ66i1^_aG1q1*9 delta 19 Zcmeyy_>GY}pO=@50SGR7xJ=}J4FEMs1#tiX diff --git a/src/gui/__pycache__/mainGui.cpython-310.pyc b/src/gui/__pycache__/mainGui.cpython-310.pyc index 2fcd01637e963826840726487b51332de78fc893..d52d6d030f50df913eeecfb0c7867a1f3deaa83e 100644 GIT binary patch delta 149 zcmZ1_zFwR+pO=@50SHX;ebZNLI#g)mZH<^Wd834DMAgTZW delta 144 zcmZ24zDk@opO=@50SMOQ`lc`6$h)4Ek$Li7R(VF&$#+>5*qDGaMU0y{*d8)6nooYk z-pp$b6wzcX5(P=vO|IgY4iRB5QUHlqO_t-7W3-=a%ee@s{sE^fqx0l{oK`@#C0C%R a7D$O1h_C?>A|S$k@_epLM%~Gr+{*xEs31rH diff --git a/src/gui/__pycache__/plotter.cpython-310.pyc b/src/gui/__pycache__/plotter.cpython-310.pyc index 296bd55c5779b54ebd6fd352236cc07391319e87..8d2e0c64c065c668ea24e11e86d71948da016850 100644 GIT binary patch delta 956 zcmZ8gO-vI(6rR~`+0u5myY2o>|0pUZT;!+*FGiv#GzL#5NDL1esua4cl9*X*tVw$z zAq)vog4t@KnCOAPN#oUnCUS%5)p+*i$%C`o(kQ#xc{}gDZ@%x%o7o@zenDA~e`%3(gP>S3iz$5%yT4NjP z8T^)gQisU8D>d;fhA8wsiM51EYz#GU13T+X)XH_ym8sak5VH|Mp4t-pIP}vbRof9y zrn2*pN`8XMZHy7^1Bsw9G^u$C&r9+=CCn7P6iqoS%uEHDwa2s{;siMdUGBs&?gL1A zTA+okX{4_4RT4Hji#)CNhIH2Gn)w1tw;lVI*s^g zs)yS8K_h4tI~#5$tS5aZnB8cirZ6i&CgA7#^*}#I8r0y?2{5=H)u|CWO%64A(4rzW zAW2Y#r+ap9X7Cwt&58v{YEcVJ9oeX3LD3PlUDLPA2&@;ljlo`tdf9MGvVp(=N9_>=*u}?@{JqfK&3ZM_Ggt40h>{jzv$%(FRYJJcTN7f}j?@ zAGF~;l_~>NY@v>q1ok9BaEj9x=tzv8utFykEWL_rn_*|AKuAref?uMMP?Ru%hKJZe z<}l@4;phBj>{|B@uy^`Zyu$wId-xgKF_!UjHf(;td+et$>2Kv!=C$i)_fg zr^qu^m~!XlXO`UC^NZ}M{Tgqxi)2_=qY4&r947@ew8Ep3uzQz`V*G_|XBY8jMshFl Q*WHh~a~R)Zzw_Vz0uD{|+W-In delta 856 zcmZ8f&1(};5TCc3HlMrQB>VNUNgKb=Uc7ivY;P73!9uAgu@qs_)ReY1ZY#(vQ6eOl z*1}T{in7t-p*N`~y(kpC2%h!oAK*ps>f22W>Mr}{&HK%7elu_O+w_+yeO=QsAfL}S zuhch>ztI;H-dMfnFZ!$NTea2Nnm=>VmT)s#?pDPQ)k+VcgT2J}tX`2wltPu??epTX zahlx|hsFuM>?b>HiQx#2K1g+yMrsDytj(IsLdn-#X-siw?hj(p|HbTMCNTP(g?y0d zDq)&3l;}cFy{-h=AV&t}DC@#m2#k$DMrxtngCOsZQJxGBFlz$l+DcIH4b-Uc3{Zcr zwpmalHOy17)ng1Ojbj{kS#!lNP@>JySc$w-9q1@a3g)AtXcP+^qS6DCOo^VvqC5vO z<1d@@u$a2$kwou zKNq}E4Rq46%Aw1)qA~1HvN0abyno6gdxQfXmGWgu$vZ0dktp>p+gOh$n~c(Ln52Xg zq{dRpJWL*&ZH~+TvpFZ1YpMB~FQ&~;qF~Lkwzy%vWxK+*@32Q=$9~WD#bsxnRmBTu zPW*J9vWj@ pd.DataFrame: return self._get_data(self.getMarkOpen(), self.calcPhaseOpen) - def get_tmovementDF(self) -> pd.DataFrame: + def get_oncomingDF(self) -> pd.DataFrame: return self._get_data(self.Ts['tmovement'], self.calcPhaseMovement) def get_weldingDF(self) -> pd.DataFrame: @@ -31,7 +31,7 @@ class idealDataBuilder(BaseIdealDataBuilder): def get_ideal_timings(self) -> list[float, float, float, float]: data = self.Ts - ideal_timings = [data['tclose'], data['tgrow'], self.welding_time, self.getMarkOpen()] + ideal_timings = [data['tclose'], data['tgrow'], self.welding_time, self.getMarkOpen()] # TODO: add data['tmovement'], Oncoming не учитывается в производительности return ideal_timings @@ -127,7 +127,17 @@ class PlotWidget(BasePlotWidget): ideal_plot = self._create_curve_ideal(stage, signal, start_timestamp, finish_timestamp) if ideal_plot: plot_widget.addItem(ideal_plot) - + + end_timestamp = time_axis[len(time_axis) - 1] + region = self._create_stage_region("Oncoming", finish_timestamp, end_timestamp) + if region: + plot_widget.addItem(region) + + for signal in description["Ideal_signals"]: + ideal_plot = self._create_curve_ideal("Oncoming", signal, finish_timestamp, end_timestamp) + if ideal_plot: + plot_widget.addItem(ideal_plot) + if settings["performance"] and all([stage in dataframe_headers for stage in self._stages]): delta_timestamp = 0 for stage in self._stages: diff --git a/src/utils/__pycache__/diagram_parser.cpython-310.pyc b/src/utils/__pycache__/diagram_parser.cpython-310.pyc index 098b2f8e6bf4cb7052119da6a19dfba5ca9cfc10..51784aea7a8ab7b1dd5a87bc7735c77190d265a0 100644 GIT binary patch delta 1019 zcmZuvTWi!n6rRaulI$hh?e@BDw->x@Q*YIlwY3G&mV(-%ctO~g5<4-h%_iGPY*8Zh z2lUAS5d_f}p)W%5NyJCrea>4SeDD{DsNkGz>8`pNa+vd-^L=OL%=z8(saN-OJ%z+K z=dIX#dwLG16yYt1-(Th>T+%{JNdeh}-@tuoB}A(#MYoWla)vJrRC3qdHLq5yy7sDH zwO!L$GPFpl(};h>cd^d9q&wZcLM(%o=K7^5{IN8HpYiw73mo$0L}8^ACPMU}gUSW8 zF0p%*JRxrJ08?Vjp{l^T4lpgoHfd5|$pb7EW7{;%UnNd-W`xe?Pz@C-_oH>h_IQ*q zrglV?Tqthzx+|1JwScHpK+PT1`;aZY!5D4qY+Q|Rn&oA=bhM&wSq>HV{FV^csi0|qOL}n^_=eomlNJC2G}4%5($zJ8lPUbAJdHK}MIOl~Aw;TyRr8q&xhamxFwXE% zGKfd{JQ*(P0LLZ^$*OM!i)LWvh2xj`78&dB#(A8QG@Qd3u_o}iBt4aW%HR1ra%Ef- zdApcp4po{`Y1;}ed!DmcT?;1ph;nh}BxIcu#=s1Y#!k1PWdv=>@yq~tQ;;yppDVK$ zTFEd)ZOK_dzG<1x?JA6kUvAKo>fBT-J#JgO+Nz+hc+{G0@V3++2`eb-AJ{V(+i9bM}OibtxF!9A_jUn;gDMD4;$)3!dd(XLd@6Nl<&5mR>nT!*7 z-giwE3onyt8fS2tgg2O$d72+68WEY-O9aqR$P}8K0b_A8OI%alrDyGF*RE?dJ|{oX zE7Xxg+T~0;*f`Yuy*5oIA8TXuf&8dFnHATxRejZn^oZPQ;aZj~YT_!_S6L;u#Tkmb z!5MIETb!x5GPi(>ZE?2ZR(MQ)(1%*%;PW=JB9j|?$s!TYrER!{HK>w~Se86(i;T$1 z60Eqh8up`OMx&kHzp@oFHOkntef`9`>Z$TAgv&Y$yVTpQ(ow` z!XX%uuULO)hQ>9Url|w#5FOOCN7_&0yZpvx1}(^1ry{ZKv161d`r)~1wLDc?2#4jo zIWabbS%(2!DzGteWEYtOvgvZw3sH9*6OPKy=IQZfaqNHM6o@bSUingK35FGnG~_eZ znL@K%4Q;pD7RWDDxqqsmdu{y~O~cl;1YSq64`Dw*o!!I^MHY!}MF_7_^w-VCBnIRc z`(QSY(LbjvdVm|32V!p~3mByUuG!>1iY%58ClOQu)y-c%y%3#|{c-*BTT+Z&D|jE_Kg7xXD*Koh3$(XbX&(I)&N zu;39v(eA!OVims~RfI)EL`96&cn-oQZy!aP{}<EVJlB85F zQBaD~wUV^f($|t+_29Ib1(nLyh0?E-J2sWIrg!7;==f0GX?pv|cGPN{%dNO^_voBa?No1AeurB+VA7qk>v+I_#pB04$wA*PUgACQWYETWE$+Ko+-^QD-kl1-uec>8VBRgZlUy(0sZ=Gt zn#J?R3hU^TtA@d7Q>lqv|N>JiylWe|iav>AU@6*+G98Lg^` zyaew5nM5&R6ZweZB0*${0`+W~s7(|_MsyJQXBADU2B?9ZcBFh-pYczHFMBS;$9yYy$cD5Kn#(gY&$xRrN`|kS$EM8}T=93OiCk4EduW z`8t_nK>M#Im@MIUxs>L1+S&Ybkf7a4_)_5>ID}snZhb6hzn*Kkl5OPM9j@-Yh^N%Bb~A3}b@!lk=~%0omRd6=7LH82(Vc`v?Co9;2k_bMVS_7?i@4Gr$G^JQ=~l>! GcKrjHrc|T= delta 1298 zcmZvaUuau(6vywm|8tXUS^nJQCT-Fr4SJW=>BP}JIF;@}VNO|{ezwaluOf=HP!f_oKT)CW-mJ`7YGqKK$37V(@LI%G3H^1Ywm`E$>? zzu)=wq4fu&$D&b7qTeTv-(A1s!|3-h_yd2B-O>?yPhF6vRAC5{R;Z^4ON2$FCyS`q z7Cg6$7(eTZ*dgK~A(G_dJ%|)Vo0Mt%UtV3N`0zFHTxSq(lec4tG`%E4r2?WPhsq6# z41C!uMYkfjY_6wJ+nSIjC3onMtM>K7UbEp%_l=3>u~uWY-Zv)aj(c9)>l+VvO+gk{ zz5E58z~v#90*jEa8b4sKss4Sm^^dUJ&oW7ZtMPBb4c;AP@$gLINBcCPCF?+cQwLt= zrX0f4$-bqLYeJHswHJ@3#%uw>!RkSW@*!W4+coe)>LBj0ZN1I!%;Sogz}xM3>NDE5 zA|#e#DkkuXY+}Qnfv@muyAI#tZRrE>G!_dPZGpnR!hw&pPX-vxy`9}`pm(DbFaXfn~ECnCBl#RkKcrGiPWlp%N%~7)b zhRNK{^b&i!EJ5-8M6T*DM5q`#AZmcs)4o|9qkZQ6R>Ppif6rnCgYKj=< z8D3Ots>t&k6KO;=$wWF4O)`-|M59Jz5~YMq6cPm*M~BD~BO)tuMB%QaO0@`$TG8hN z8XONE9{L>q+9(Z|Apay=kF(5>xO!jnADyjx{y3Xnz{m2X#EXnCv+&{eq2VK*%ijo_ z_-TGldxmT(?k_a74v~TDg&FM>k%jq@6A;DMN1o75(mqBpWvmuMc)mCX35qM@c@|0c^x zmKBz_`O<>{`jfV;B#9|)1539|OW9g+#b4a`psWGp@WSXk6me(eVE#SMf0yN|L5P#B zvhiA_t-%`4O*qu@=BHZoCz_s%W7Xa84n9)7USH$X_i?#;GputL+A0~cc&X~ZD*j#F b3ukf9uBIN`*D7{$Y5aKC4VoFVl9hh}yF)R0 diff --git a/src/utils/base/base.py b/src/utils/base/base.py index e1de8b9..ee0fd86 100644 --- a/src/utils/base/base.py +++ b/src/utils/base/base.py @@ -104,17 +104,18 @@ class BasePlotWidget: self._mediator = mediator self._stages = [ - "Relief", "Closing", "Squeeze", - "Welding" + "Welding", + "Relief" ] self._stage_colors = { "Closing": [208, 28, 31, 100], "Squeeze": [45, 51, 89, 150], "Welding": [247, 183, 24, 100], - "Relief": [0, 134, 88, 100] + "Relief": [0, 134, 88, 100], + "Oncoming": [222, 184, 135, 100] } self._plt_channels = { "Electrode Force, N & Welding Current, kA": { @@ -208,7 +209,8 @@ class BasePlotWidget: "Closing": self._opt.get_closingDF(), "Squeeze": self._opt.get_compressionDF(), "Welding": self._opt.get_weldingDF(), - "Relief": self._opt.get_openingDF() + "Relief": self._opt.get_openingDF(), + "Oncoming": self._opt.get_oncomingDF() } @property def mediator(self) -> BaseMediator: @@ -271,6 +273,9 @@ class BaseIdealDataBuilder(OptAlgorithm): def get_weldingDF(self) -> pd.DataFrame: ... + + def get_oncomingDF(self) -> pd.DataFrame: + ... def get_ideal_timings(self) -> list[float, float, float, float]: ...