From 13dce799e1ecb2a0193c3f3870b0e9882d2aff48 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Wed, 7 May 2025 15:10:26 +0200 Subject: [PATCH 01/17] edit workout to speed test --- settings/workouts.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/settings/workouts.csv b/settings/workouts.csv index 7afcf49..4b066a6 100644 --- a/settings/workouts.csv +++ b/settings/workouts.csv @@ -2,3 +2,4 @@ Name;Description;Sets;Set Pause;Repetitions;Repetition Active;Repetition Pause Critical Force Test;The classical finger flexor critical force test (ff-CF). 7 sec on, 3 sec off for 4 min in total. Pull as hard as you can.;1;5;24;7;3 Max Isometric Finger Strength;Test the maximal isometric finger strength (MIFS). Hang for 5 sec with 120 sec pause (3 sets).;3;120;1;5;0 Warm-up;This can be used as warm-up for the critical force test. Switch hands after each repetition (10 min).;10;35;2;10;5 +Speed test;This is a test;10;20;30;40;50 \ No newline at end of file From 736426f10d3ddb8a74d80cfb953878658bce858e Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Tue, 13 May 2025 14:24:35 +0200 Subject: [PATCH 02/17] amendment for two sensor --- util/sensor.py | 64 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/util/sensor.py b/util/sensor.py index 8d2147e..46026a1 100644 --- a/util/sensor.py +++ b/util/sensor.py @@ -31,7 +31,8 @@ #======================================== class WeightSensor(): def __init__(self): - self.sensorValue = 0 + self.sensorValue_1 = 0 + self.sensorValue_2 = 0 self.scalingFactor = self.calcScalingFactor(Params.calibrationFile.value) # Set environment variable for MCP2221A @@ -44,13 +45,23 @@ def __init__(self): try: import board from util.cedargrove_nau7802 import NAU7802 + from adafruit_tca9548a import TCA9548A + + #Multiplexer initialisieren + multiplexer = TCA9548A(board.I2C()) # Instantiate 24-bit load sensor ADC; two channels, default gain of 128 - self.nau7802 = NAU7802(board.I2C(), address=0x2A, active_channels=2) - self.nau7802.enable(True) - self.nau7802.channel = 1 + self.nau7802_1 = NAU7802(multiplexer[0], address=0x2A, active_channels=2) + self.nau7802_1.enable(True) + self.nau7802_1.channel = 1 self.zero_channel() + #2.Wägezelle + self.nau7802_2 = NAU7802(multiplexer[1], address=0x2A, active_channels=2) + self.nau7802_2.enable(True) + self.nau7802_2.channel = 1 + self.zero_channel_2() + self.connected = True self.stopThreadEvent = Event() @@ -70,10 +81,12 @@ def onNewMeasurement(self, stopEvent): if stopEvent.is_set(): stopEvent.clear() break - elif self.connected and self.nau7802.available: - self.sensorValue = self.nau7802.read() + elif self.connected and self.nau7802_1.available and self.nau7802_2.available: + self.sensorValue_1 = self.nau7802_1.read() + self.sensorValue_2 = self.nau7802_2.read() else: - self.sensorValue = 0 + self.sensorValue_1 = 0 + self.sensorValue_2 = 0 time.sleep(0.001) def zero_channel(self): @@ -84,20 +97,41 @@ def zero_channel(self): msg = QMessageBox() msg.setWindowTitle("Warning") msg.setIcon(QMessageBox.Warning) - msg.setText("Checking sensor...\nRemove any weight, then click \"OK\" to proceed.") + msg.setText("Checking sensor 1 ...\nRemove any weight, then click \"OK\" to proceed.") msg.exec_() - self.nau7802.calibrate("INTERNAL") - self.nau7802.calibrate("OFFSET") + self.nau7802_1.calibrate("INTERNAL") + self.nau7802_1.calibrate("OFFSET") for _ in range(100): - self.nau7802.read() # Read 100 samples to establish zero offset + self.nau7802_1.read() # Read 100 samples to establish zero offset + + def zero_channel_2(self): + """Initiate internal calibration for current channel; return raw zero + offset value. Use when scale is started, a new channel is selected, or to + adjust for measurement drift. Remove weight and tare from load cell before + executing.""" + msg = QMessageBox() + msg.setWindowTitle("Warning") + msg.setIcon(QMessageBox.Warning) + msg.setText("Checking sensor 2 ...\nRemove any weight, then click \"OK\" to proceed.") + msg.exec_() + + self.nau7802_2.calibrate("INTERNAL") + self.nau7802_2.calibrate("OFFSET") + + for _ in range(100): + self.nau7802_2.read() # Read 100 samples to establish zero offset - def getValueInKg(self): - return self.sensorValue * self.scalingFactor + def getValueInKg_1(self): + return self.sensorValue_1 * self.scalingFactor + def getValueInKg_2(self): + return self.sensorValue_2 * self.scalingFactor - def getRawValue(self): - return self.sensorValue + def getRawValue_1(self): + return self.sensorValue_1 + def getRawValue_2(self): + return self.sensorValue_2 def isConnected(self): return self.connected From 5d387b00903b8899618291beec33261aa7d69c65 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Tue, 13 May 2025 14:28:57 +0200 Subject: [PATCH 03/17] workout for speed test --- settings/workouts.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings/workouts.csv b/settings/workouts.csv index 4b066a6..7cea173 100644 --- a/settings/workouts.csv +++ b/settings/workouts.csv @@ -2,4 +2,4 @@ Name;Description;Sets;Set Pause;Repetitions;Repetition Active;Repetition Pause Critical Force Test;The classical finger flexor critical force test (ff-CF). 7 sec on, 3 sec off for 4 min in total. Pull as hard as you can.;1;5;24;7;3 Max Isometric Finger Strength;Test the maximal isometric finger strength (MIFS). Hang for 5 sec with 120 sec pause (3 sets).;3;120;1;5;0 Warm-up;This can be used as warm-up for the critical force test. Switch hands after each repetition (10 min).;10;35;2;10;5 -Speed test;This is a test;10;20;30;40;50 \ No newline at end of file +Speed test;This is a test;2;120;1;5;0 \ No newline at end of file From 5ad3557cd5f649060577675740409dff83587554 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Tue, 13 May 2025 14:39:03 +0200 Subject: [PATCH 04/17] Anpassung Measurment --- ui/MeasurementCtrl.py | 102 +++++++++++++++++++++++++++--------------- ui/MeasurementGui.py | 7 +++ 2 files changed, 73 insertions(+), 36 deletions(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 2ea76c4..3647f41 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -60,18 +60,20 @@ def __init__(self, weightSensor): self.running = False self.lookupTable = 0 self.countdown = 0 - self.numMeasSamples = 0 + self.numMeasSamples_1 = 0 + self.numMeasSamples_2 = 0 self.numSets = 0 self.numRepsPerSet = 0 self.measCnt = 0 self.secCnt = 0 self.repCnt = 0 self.setCnt = 1 - self.currentWeight = 0 + self.currentWeight_1 = 0 self.tare = 0 # Data, that will be stored in result file - self.measDataKg = np.asarray([]) + self.measDataKg_1 = np.asarray([]) + self.measDataKg_2 = np.asarray([]) self.timestamp = 'unknown' self.bodyWeight = form.bodyWeightSpinBox.value() self.criticalForce = 0 @@ -97,11 +99,12 @@ def __init__(self, weightSensor): self.workoutComboBox = form.workoutComboBox self.workoutLabel = form.workoutLabel self.weightSpinBox = form.bodyWeightSpinBox - self.graphicsView = form.graphicsView + self.graphicsView_1 = form.graphicsView self.tareButton = form.tareButton - self.tareLabel = form.tareLabel + self.tareLabel_1 = form.tareLabel + self.tareLabel_2 = form.tareLabel_2 - self.graphicsView.setBackground('w') + self.graphicsView_1.setBackground('w') #======================================== # Workout handling @@ -134,8 +137,10 @@ def __init__(self, weightSensor): def onStartMeasurement(self): if not self.running: self.tareTimer.stop() - self.numMeasSamples = len(self.lookupTable) * self.fsMeas - self.measDataKg = np.zeros(self.numMeasSamples) + self.numMeasSamples_1 = len(self.lookupTable) * self.fsMeas + self.numMeasSamples_2 = len(self.lookupTable) * self.fsMeas + self.measDataKg_1 = np.zeros(self.numMeasSamples_1) + self.measDataKg_2 = np.zeros(self.numMeasSamples_2) self.workoutComboBox.setEnabled(False) self.weightSpinBox.setEnabled(False) @@ -170,14 +175,17 @@ def onStopMeasurement(self): def onMeasurementCallback(self): secCnt = self.secCnt - if self.measCnt >= self.numMeasSamples: + if self.measCnt >= self.numMeasSamples_1: # Measurement finished self.measFinished.trigger() else: # Read value from sensor and save it to array - valueKg = self.weightSensor.getValueInKg() - self.tare - self.tareLabel.setText(str(np.around(valueKg, decimals=2)) + 'kg') - self.measDataKg[self.measCnt] = valueKg + valueKg_1 = self.weightSensor.getValueInKg_1() - self.tare + valueKg_2 = self.weightSensor.getValueInKg_2() - self.tare + self.tareLabel_1.setText(str(np.around(valueKg_1, decimals=2)) + 'kg') + self.tareLabel_2.setText(str(np.around(valueKg_2, decimals=2)) + 'kg') + self.measDataKg_1[self.measCnt] = valueKg_1 + self.measDataKg_2[self.measCnt] = valueKg_2 # Workout timer handling if self.measCnt % self.fsMeas == 0: @@ -222,12 +230,15 @@ def onMeasurementCallback(self): self.measCnt += 1 def onTareVisualization(self): - self.currentWeight = self.weightSensor.getValueInKg() - weightString = str(np.around(self.currentWeight - self.tare, decimals=2)) - self.tareLabel.setText(weightString + 'kg') + self.currentWeight_1 = self.weightSensor.getValueInKg_1() + self.currentWeight_2 = self.weightSensor.getValueInKg_2() + weightString_1 = str(np.around(self.currentWeight_1 - self.tare, decimals=2)) + weightString_2 = str(np.around(self.currentWeight_2 - self.tare, decimals=2)) + self.tareLabel_1.setText(weightString_1 + 'kg') + self.tareLabel_2.setText(weightString_2 + 'kg') def onTareButtonClicked(self): - self.tare = self.currentWeight + self.tare = self.currentWeight_1 def onWorkoutChanged(self, id): self.workoutDescriptionLabel.setText(self.workoutHandler.getWorkoutDescription(id)) @@ -237,7 +248,7 @@ def onWorkoutChanged(self, id): def onBodyWeightChanged(self, value): self.bodyWeight = value - if len(self.measDataKg) > 0: + if len(self.measDataKg_1) > 0: self.computeResultAndPlot() def onCloseApplication(self): @@ -249,27 +260,29 @@ def onCloseApplication(self): #======================================== def computeResultAndPlot(self): # Compute result (force as percentage of body weight) - measDataPercentBw = self.measDataKg / self.bodyWeight * 100 - + measDataPercentBw_1 = self.measDataKg_1 / self.bodyWeight * 100 + measDataPercentBw_2 = self.measDataKg_2 / self.bodyWeight * 100 # Compensate delay between audio clicks and measurement - measDataPercentBw = np.roll(measDataPercentBw, -self.delayInSamples) - measDataPercentBw[-self.delayInSamples:] = 0 + measDataPercentBw_1 = np.roll(measDataPercentBw_1, -self.delayInSamples) + measDataPercentBw_2 = np.roll(measDataPercentBw_2, -self.delayInSamples) + measDataPercentBw_1[-self.delayInSamples:] = 0 + measDataPercentBw_2[-self.delayInSamples:] = 0 # Compute the mean force during repetition active times - repMean = computeRepetitionMean(measDataPercentBw, self.lookupTable, self.fsMeas) + repMean = computeRepetitionMean(measDataPercentBw_1, self.lookupTable, self.fsMeas) # Prepare plot - t = np.linspace(0, len(measDataPercentBw) / self.fsMeas, len(measDataPercentBw)) - self.graphicsView.clear() - self.graphicsView.addLegend().anchor(itemPos=(1,0), parentPos=(1,0), offset=(-10,10)) + t = np.linspace(0, len(measDataPercentBw_1) / self.fsMeas, len(measDataPercentBw_1)) + self.graphicsView_1.clear() + self.graphicsView_1.addLegend().anchor(itemPos=(1,0), parentPos=(1,0), offset=(-10,10)) # Plot raw measurement data pen = pg.mkPen(color=(150,150,150), width=2) - self.graphicsView.plot(t, measDataPercentBw, name="Raw Data", pen=pen) + self.graphicsView_1.plot(t, measDataPercentBw_1, name="Raw Data", pen=pen) # Plot mean of each repetition block pen = pg.mkPen(color=(80,80,80), width=2) - self.graphicsView.plot(t, repMean, name="Rep. Mean", pen=pen) + self.graphicsView_1.plot(t, repMean, name="Rep. Mean", pen=pen) # Compute the critical force, if necessary cf = 0 @@ -282,16 +295,31 @@ def computeResultAndPlot(self): W = np.around(W, decimals = 2) pen = pg.mkPen(color=(0,180,0), width=2) - self.graphicsView.plot([t[0],t[-1]], [cf,cf], name="CF = " + str(cf) + " %BW | W\' = " + str(W) + " %BWs", pen=pen) + self.graphicsView_1.plot([t[0],t[-1]], [cf,cf], name="CF = " + str(cf) + " %BW | W\' = " + str(W) + " %BWs", pen=pen) + ### NEU: Schnellkrafttest + workout_name = self.workoutHandler.getWorkoutName(self.selectedWorkoutId) + if workout_name == 'Speed test': + # Beispielhafte Logik: Maxwert innerhalb einer kurzen Zeitspanne suchen + max_peak_1 = np.max(measDataPercentBw_1) + peak_time_1 = t[np.argmax(measDataPercentBw_1)] + max_peak_2 = np.max(measDataPercentBw_2) + peak_time_2 = t[np.argmax(measDataPercentBw_2)] + + pen = pg.mkPen(color=(0, 0, 255), width=2) + self.graphicsView_1.plot([peak_time_1], [max_peak_1], pen=None, symbol='o', symbolBrush='b', name="Peak Force_1") + self.graphicsView_1.plot([t[0], t[-1]], [max_peak_1, max_peak_1], pen=pen, name="Max. Power_1 = " + str(np.around(max_peak_1, 2)) + " %BW") + self.graphicsView_1.plot([peak_time_2], [max_peak_2], pen=None, symbol='o', symbolBrush='b', name="Peak Force_2") + self.graphicsView_1.plot([t[0], t[-1]], [max_peak_2, max_peak_2], pen=pen, name="Max. Power_2 = " + str(np.around(max_peak_2, 2)) + " %BW") + ### ENDE: Schnellkrafttest # Plot maximum force pen = pg.mkPen(color=(180,0,0), width=2) mf = computeMaxForce(repMean) - self.graphicsView.plot([t[0],t[-1]], [mf,mf], name="Max. Force = " + str(mf) + " %BW", pen=pen) + self.graphicsView_1.plot([t[0],t[-1]], [mf,mf], name="Max. Force = " + str(mf) + " %BW", pen=pen) - self.graphicsView.showGrid(x=True, y=True) - self.graphicsView.setLabel('left', "%BW") - self.graphicsView.setLabel('bottom', "Time [sec]") + self.graphicsView_1.showGrid(x=True, y=True) + self.graphicsView_1.setLabel('left', "%BW") + self.graphicsView_1.setLabel('bottom', "Time [sec]") # Store result in class member variables self.criticalForce = cf @@ -309,7 +337,8 @@ def getData(self): data['criticalForce'] = float(self.criticalForce) data['wPrime'] = float(self.wPrime) data['maxForce'] = float(self.maxForce) - data['measDataKg'] = self.measDataKg.tolist() + data['measDataKg_1'] = self.measDataKg_1.tolist() + data['measDataKg_2'] = self.measDataKg_2.tolist() return data def setData(self, data, reset=False): @@ -317,12 +346,13 @@ def setData(self, data, reset=False): workoutId = self.workoutHandler.getIdFromName(self.workoutName) self.workoutComboBox.setCurrentIndex(workoutId) self.timestamp = data['timestamp'] - self.measDataKg = np.asarray(data['measDataKg']) + self.measDataKg_1 = np.asarray(data['measDataKg_1']) + self.measDataKg_2 = np.asarray(data['measDataKg_2']) # The order is critical, always do this at the end self.weightSpinBox.setValue(data['weight']) - if not reset and len(self.measDataKg) > 0: + if not reset and len(self.measDataKg_1) > 0: # Since critical force, W' and max force will be re-calculated in # the following function, it's not necessary to load them here. self.computeResultAndPlot() @@ -331,5 +361,5 @@ def setData(self, data, reset=False): self.criticalForce = 0 self.wPrime = 0 self.maxForce = 0 - self.graphicsView.clear() + self.graphicsView_1.clear() diff --git a/ui/MeasurementGui.py b/ui/MeasurementGui.py index d2fdacf..14f78b5 100644 --- a/ui/MeasurementGui.py +++ b/ui/MeasurementGui.py @@ -116,6 +116,12 @@ def setupUi(self, Form): self.tareLabel.setFont(font) self.tareLabel.setAlignment(Qt.AlignCenter) + self.tareLabel_2 = QLabel(Form) + self.tareLabel_2.setObjectName(u"tareLabel") + self.tareLabel_2.setMinimumSize(QSize(70, 0)) + self.tareLabel_2.setFont(font) + self.tareLabel_2.setAlignment(Qt.AlignCenter) + self.verticalLayout_3.addWidget(self.tareLabel) self.tareButton = QPushButton(Form) @@ -157,6 +163,7 @@ def retranslateUi(self, Form): self.stopButton.setText(QCoreApplication.translate("Form", u"Stop", None)) self.workoutLabel.setText(QCoreApplication.translate("Form", u"Stopped", None)) self.tareLabel.setText(QCoreApplication.translate("Form", u"0kg", None)) + self.tareLabel_2.setText(QCoreApplication.translate("Form", u"0kg", None)) self.tareButton.setText(QCoreApplication.translate("Form", u"Tare", None)) # retranslateUi From 77108440ce758f826bebebb588d39a7f65277901 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Wed, 14 May 2025 14:06:53 +0200 Subject: [PATCH 05/17] MasurmentCtrl angepasst --- ui/MeasurementCtrl.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 3647f41..8bec01f 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -278,7 +278,9 @@ def computeResultAndPlot(self): # Plot raw measurement data pen = pg.mkPen(color=(150,150,150), width=2) - self.graphicsView_1.plot(t, measDataPercentBw_1, name="Raw Data", pen=pen) + pen_2 = pg.mkPen(color=(180,180,180), width=2) + self.graphicsView_1.plot(t, measDataPercentBw_1, name="Raw Data_1", pen=pen) + self.graphicsView_1.plot(t, measDataPercentBw_2, name="Raw Data_2", pen=pen_2) # Plot mean of each repetition block pen = pg.mkPen(color=(80,80,80), width=2) @@ -306,6 +308,9 @@ def computeResultAndPlot(self): peak_time_2 = t[np.argmax(measDataPercentBw_2)] pen = pg.mkPen(color=(0, 0, 255), width=2) + #RFD Development + #self.graphicsView_1.plot([peak_time_1], [max_peak_1], pen=None, symbol='o', symbolBrush='b', name="Peak Force_1") + #self.graphicsView_1.plot([t[0], t[-1]], [max_peak_1, max_peak_1], pen=pen, name="Max. Power_1 = " + str(np.around(max_peak_1, 2)) + " %BW") self.graphicsView_1.plot([peak_time_1], [max_peak_1], pen=None, symbol='o', symbolBrush='b', name="Peak Force_1") self.graphicsView_1.plot([t[0], t[-1]], [max_peak_1, max_peak_1], pen=pen, name="Max. Power_1 = " + str(np.around(max_peak_1, 2)) + " %BW") self.graphicsView_1.plot([peak_time_2], [max_peak_2], pen=None, symbol='o', symbolBrush='b', name="Peak Force_2") From efff564ee39b5afce7d73a158b6924709520cfa3 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Wed, 14 May 2025 14:48:20 +0200 Subject: [PATCH 06/17] neu --- ui/MeasurementCtrl.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 8bec01f..6802c12 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -277,9 +277,11 @@ def computeResultAndPlot(self): self.graphicsView_1.addLegend().anchor(itemPos=(1,0), parentPos=(1,0), offset=(-10,10)) # Plot raw measurement data - pen = pg.mkPen(color=(150,150,150), width=2) - pen_2 = pg.mkPen(color=(180,180,180), width=2) + pen = pg.mkPen(color=(150,150,150), width=2) self.graphicsView_1.plot(t, measDataPercentBw_1, name="Raw Data_1", pen=pen) + + #if bedingung vom Speed test + pen_2 = pg.mkPen(color=(180,180,180), width=2) self.graphicsView_1.plot(t, measDataPercentBw_2, name="Raw Data_2", pen=pen_2) # Plot mean of each repetition block From 4dce41b810fe092d621d1e7a37731b7c9f88977b Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Wed, 14 May 2025 15:06:47 +0200 Subject: [PATCH 07/17] neue GUI Editoren --- ui/CalibrationGui.py | 4 ++-- ui/CompareresultGui.py | 2 +- ui/DataGui.py | 2 +- ui/MeasurementGui.py | 17 ++++++++--------- ui/MeasurementGui.ui | 11 +++++++++-- ui/PreferencesGui.py | 4 ++-- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/ui/CalibrationGui.py b/ui/CalibrationGui.py index 54dfd4f..7a4133c 100644 --- a/ui/CalibrationGui.py +++ b/ui/CalibrationGui.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'CalibrationGui.ui' ## -## Created by: Qt User Interface Compiler version 6.4.2 +## Created by: Qt User Interface Compiler version 6.6.2 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ @@ -119,7 +119,7 @@ def setupUi(self, Form): self.verticalLayout.addWidget(self.line_3) - self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) + self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) self.verticalLayout.addItem(self.verticalSpacer) diff --git a/ui/CompareresultGui.py b/ui/CompareresultGui.py index fd001e5..5831d93 100644 --- a/ui/CompareresultGui.py +++ b/ui/CompareresultGui.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'CompareresultGui.ui' ## -## Created by: Qt User Interface Compiler version 6.4.2 +## Created by: Qt User Interface Compiler version 6.6.2 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ diff --git a/ui/DataGui.py b/ui/DataGui.py index b694570..f0d2898 100644 --- a/ui/DataGui.py +++ b/ui/DataGui.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'DataGui.ui' ## -## Created by: Qt User Interface Compiler version 6.4.2 +## Created by: Qt User Interface Compiler version 6.6.2 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ diff --git a/ui/MeasurementGui.py b/ui/MeasurementGui.py index 14f78b5..6b88229 100644 --- a/ui/MeasurementGui.py +++ b/ui/MeasurementGui.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'MeasurementGui.ui' ## -## Created by: Qt User Interface Compiler version 6.4.2 +## Created by: Qt User Interface Compiler version 6.6.2 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ @@ -25,7 +25,7 @@ class Ui_Form(object): def setupUi(self, Form): if not Form.objectName(): Form.setObjectName(u"Form") - Form.resize(542, 488) + Form.resize(541, 488) self.verticalLayout = QVBoxLayout(Form) self.verticalLayout.setObjectName(u"verticalLayout") self.horizontalLayout_2 = QHBoxLayout() @@ -116,14 +116,13 @@ def setupUi(self, Form): self.tareLabel.setFont(font) self.tareLabel.setAlignment(Qt.AlignCenter) - self.tareLabel_2 = QLabel(Form) - self.tareLabel_2.setObjectName(u"tareLabel") - self.tareLabel_2.setMinimumSize(QSize(70, 0)) - self.tareLabel_2.setFont(font) - self.tareLabel_2.setAlignment(Qt.AlignCenter) - self.verticalLayout_3.addWidget(self.tareLabel) + self.test = QLabel(Form) + self.test.setObjectName(u"test") + + self.verticalLayout_3.addWidget(self.test) + self.tareButton = QPushButton(Form) self.tareButton.setObjectName(u"tareButton") self.tareButton.setMinimumSize(QSize(70, 0)) @@ -163,7 +162,7 @@ def retranslateUi(self, Form): self.stopButton.setText(QCoreApplication.translate("Form", u"Stop", None)) self.workoutLabel.setText(QCoreApplication.translate("Form", u"Stopped", None)) self.tareLabel.setText(QCoreApplication.translate("Form", u"0kg", None)) - self.tareLabel_2.setText(QCoreApplication.translate("Form", u"0kg", None)) + self.test.setText(QCoreApplication.translate("Form", u"TextLabel", None)) self.tareButton.setText(QCoreApplication.translate("Form", u"Tare", None)) # retranslateUi diff --git a/ui/MeasurementGui.ui b/ui/MeasurementGui.ui index 33f816d..bc46d19 100644 --- a/ui/MeasurementGui.ui +++ b/ui/MeasurementGui.ui @@ -6,7 +6,7 @@ 0 0 - 542 + 541 488 @@ -123,7 +123,7 @@ - + QLayout::SetDefaultConstraint @@ -148,6 +148,13 @@ + + + + TextLabel + + + diff --git a/ui/PreferencesGui.py b/ui/PreferencesGui.py index c53473f..fed964d 100644 --- a/ui/PreferencesGui.py +++ b/ui/PreferencesGui.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'PreferencesGui.ui' ## -## Created by: Qt User Interface Compiler version 6.4.2 +## Created by: Qt User Interface Compiler version 6.6.2 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ @@ -58,7 +58,7 @@ def setupUi(self, Form): self.verticalLayout.addWidget(self.warningLabel) - self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) + self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) self.verticalLayout.addItem(self.verticalSpacer) From 93485d8d45ae93d9d226d8ef62b4c6a550cb1432 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Thu, 15 May 2025 13:57:51 +0200 Subject: [PATCH 08/17] new gui --- ui/MeasurementGui.py | 71 ++++++++++++++++++---------- ui/MeasurementGui.ui | 109 +++++++++++++++++++++++++------------------ 2 files changed, 110 insertions(+), 70 deletions(-) diff --git a/ui/MeasurementGui.py b/ui/MeasurementGui.py index 6b88229..692d88e 100644 --- a/ui/MeasurementGui.py +++ b/ui/MeasurementGui.py @@ -25,7 +25,7 @@ class Ui_Form(object): def setupUi(self, Form): if not Form.objectName(): Form.setObjectName(u"Form") - Form.resize(541, 488) + Form.resize(595, 488) self.verticalLayout = QVBoxLayout(Form) self.verticalLayout.setObjectName(u"verticalLayout") self.horizontalLayout_2 = QHBoxLayout() @@ -66,6 +66,13 @@ def setupUi(self, Form): self.verticalLayout.addWidget(self.line_3) + self.line_4 = QFrame(Form) + self.line_4.setObjectName(u"line_4") + self.line_4.setFrameShape(QFrame.HLine) + self.line_4.setFrameShadow(QFrame.Sunken) + + self.verticalLayout.addWidget(self.line_4) + self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName(u"horizontalLayout") self.verticalLayout_2 = QVBoxLayout() @@ -110,37 +117,52 @@ def setupUi(self, Form): self.verticalLayout_3 = QVBoxLayout() self.verticalLayout_3.setObjectName(u"verticalLayout_3") self.verticalLayout_3.setSizeConstraint(QLayout.SetDefaultConstraint) - self.tareLabel = QLabel(Form) - self.tareLabel.setObjectName(u"tareLabel") - self.tareLabel.setMinimumSize(QSize(70, 0)) - self.tareLabel.setFont(font) - self.tareLabel.setAlignment(Qt.AlignCenter) + self.horizontalLayout_3 = QHBoxLayout() + self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") + self.tareLabel_1 = QLabel(Form) + self.tareLabel_1.setObjectName(u"tareLabel_1") + sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tareLabel_1.sizePolicy().hasHeightForWidth()) + self.tareLabel_1.setSizePolicy(sizePolicy) + font1 = QFont() + font1.setPointSize(15) + self.tareLabel_1.setFont(font1) + self.tareLabel_1.setAlignment(Qt.AlignCenter) - self.verticalLayout_3.addWidget(self.tareLabel) + self.horizontalLayout_3.addWidget(self.tareLabel_1) - self.test = QLabel(Form) - self.test.setObjectName(u"test") + self.tareLabel_2 = QLabel(Form) + self.tareLabel_2.setObjectName(u"tareLabel_2") + self.tareLabel_2.setFont(font1) + self.tareLabel_2.setAlignment(Qt.AlignCenter) - self.verticalLayout_3.addWidget(self.test) + self.horizontalLayout_3.addWidget(self.tareLabel_2) - self.tareButton = QPushButton(Form) - self.tareButton.setObjectName(u"tareButton") - self.tareButton.setMinimumSize(QSize(70, 0)) - self.verticalLayout_3.addWidget(self.tareButton) + self.verticalLayout_3.addLayout(self.horizontalLayout_3) + self.horizontalLayout_4 = QHBoxLayout() + self.horizontalLayout_4.setObjectName(u"horizontalLayout_4") + self.tareButton_1 = QPushButton(Form) + self.tareButton_1.setObjectName(u"tareButton_1") - self.horizontalLayout.addLayout(self.verticalLayout_3) + self.horizontalLayout_4.addWidget(self.tareButton_1) + self.tareButton_2 = QPushButton(Form) + self.tareButton_2.setObjectName(u"tareButton_2") - self.verticalLayout.addLayout(self.horizontalLayout) + self.horizontalLayout_4.addWidget(self.tareButton_2) - self.line_4 = QFrame(Form) - self.line_4.setObjectName(u"line_4") - self.line_4.setFrameShape(QFrame.HLine) - self.line_4.setFrameShadow(QFrame.Sunken) - self.verticalLayout.addWidget(self.line_4) + self.verticalLayout_3.addLayout(self.horizontalLayout_4) + + + self.horizontalLayout.addLayout(self.verticalLayout_3) + + + self.verticalLayout.addLayout(self.horizontalLayout) self.graphicsView = PlotWidget(Form) self.graphicsView.setObjectName(u"graphicsView") @@ -161,8 +183,9 @@ def retranslateUi(self, Form): self.startButton.setText(QCoreApplication.translate("Form", u"Start", None)) self.stopButton.setText(QCoreApplication.translate("Form", u"Stop", None)) self.workoutLabel.setText(QCoreApplication.translate("Form", u"Stopped", None)) - self.tareLabel.setText(QCoreApplication.translate("Form", u"0kg", None)) - self.test.setText(QCoreApplication.translate("Form", u"TextLabel", None)) - self.tareButton.setText(QCoreApplication.translate("Form", u"Tare", None)) + self.tareLabel_1.setText(QCoreApplication.translate("Form", u"0kg", None)) + self.tareLabel_2.setText(QCoreApplication.translate("Form", u"0kg", None)) + self.tareButton_1.setText(QCoreApplication.translate("Form", u"Tare 1", None)) + self.tareButton_2.setText(QCoreApplication.translate("Form", u"Tare 2", None)) # retranslateUi diff --git a/ui/MeasurementGui.ui b/ui/MeasurementGui.ui index bc46d19..7717913 100644 --- a/ui/MeasurementGui.ui +++ b/ui/MeasurementGui.ui @@ -6,7 +6,7 @@ 0 0 - 541 + 595 488 @@ -67,6 +67,13 @@ + + + + Qt::Horizontal + + + @@ -123,62 +130,72 @@ - + QLayout::SetDefaultConstraint - - - - 70 - 0 - - - - - 13 - - - - 0kg - - - Qt::AlignCenter - - + + + + + + 0 + 0 + + + + + 15 + + + + 0kg + + + Qt::AlignCenter + + + + + + + + 15 + + + + 0kg + + + Qt::AlignCenter + + + + - - - TextLabel - - - - - - - - 70 - 0 - - - - Tare - - + + + + + Tare 1 + + + + + + + Tare 2 + + + + - - - - Qt::Horizontal - - - From 81c7953dda31368fbe7d4492596d85753710389b Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Sat, 17 May 2025 14:48:31 +0200 Subject: [PATCH 09/17] MeasurmentCtrl neu --- ui/MeasurementCtrl.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 6802c12..578f932 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -85,7 +85,7 @@ def __init__(self, weightSensor): #======================================== form.startButton.pressed.connect(self.onStartMeasurement) form.stopButton.pressed.connect(self.onStopMeasurement) - form.tareButton.pressed.connect(self.onTareButtonClicked) + form.tareButton_1.pressed.connect(self.onTareButtonClicked) form.bodyWeightSpinBox.valueChanged.connect(self.onBodyWeightChanged) # Action, triggered when measurement is finished @@ -100,8 +100,9 @@ def __init__(self, weightSensor): self.workoutLabel = form.workoutLabel self.weightSpinBox = form.bodyWeightSpinBox self.graphicsView_1 = form.graphicsView - self.tareButton = form.tareButton - self.tareLabel_1 = form.tareLabel + self.tareButton_1 = form.tareButton_1 + self.tareButton_2 = form.tareButton_2 + self.tareLabel_1 = form.tareLabel_1 self.tareLabel_2 = form.tareLabel_2 self.graphicsView_1.setBackground('w') @@ -144,7 +145,8 @@ def onStartMeasurement(self): self.workoutComboBox.setEnabled(False) self.weightSpinBox.setEnabled(False) - self.tareButton.setEnabled(False) + self.tareButton_1.setEnabled(False) + self.tareButton_2.setEnabled(False) self.measurementTimer = RepeatedTimer(1/self.fsMeas, self.onMeasurementCallback) @@ -165,7 +167,8 @@ def onStopMeasurement(self): self.workoutComboBox.setEnabled(True) self.weightSpinBox.setEnabled(True) - self.tareButton.setEnabled(True) + self.tareButton_1.setEnabled(True) + self.tareButton_2.setEnabled(True) self.tareTimer = RepeatedTimer(1/self.fsMeas, self.onTareVisualization) @@ -280,10 +283,6 @@ def computeResultAndPlot(self): pen = pg.mkPen(color=(150,150,150), width=2) self.graphicsView_1.plot(t, measDataPercentBw_1, name="Raw Data_1", pen=pen) - #if bedingung vom Speed test - pen_2 = pg.mkPen(color=(180,180,180), width=2) - self.graphicsView_1.plot(t, measDataPercentBw_2, name="Raw Data_2", pen=pen_2) - # Plot mean of each repetition block pen = pg.mkPen(color=(80,80,80), width=2) self.graphicsView_1.plot(t, repMean, name="Rep. Mean", pen=pen) @@ -303,6 +302,9 @@ def computeResultAndPlot(self): ### NEU: Schnellkrafttest workout_name = self.workoutHandler.getWorkoutName(self.selectedWorkoutId) if workout_name == 'Speed test': + #second scales + pen_2 = pg.mkPen(color=(0,0,0), width=2) + self.graphicsView_1.plot(t, measDataPercentBw_2, name="Raw Data_2", pen=pen_2) # Beispielhafte Logik: Maxwert innerhalb einer kurzen Zeitspanne suchen max_peak_1 = np.max(measDataPercentBw_1) peak_time_1 = t[np.argmax(measDataPercentBw_1)] From ad4ae7d0974b7d87f81a64c82f97be5b21f52b83 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Sat, 17 May 2025 15:15:39 +0200 Subject: [PATCH 10/17] MeasurmentCtrl neu --- ui/MeasurementCtrl.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 578f932..0d2ed24 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -55,7 +55,8 @@ def __init__(self, weightSensor): self.delayInSamples = round(pref['delayCompensation']/1000 * self.fsMeas) #======================================== - # Init class members + # Init class members1,5 + #======================================== self.running = False self.lookupTable = 0 @@ -69,7 +70,8 @@ def __init__(self, weightSensor): self.repCnt = 0 self.setCnt = 1 self.currentWeight_1 = 0 - self.tare = 0 + self.tare_1 = 0 + self.tare_2 = 0 # Data, that will be stored in result file self.measDataKg_1 = np.asarray([]) @@ -85,7 +87,8 @@ def __init__(self, weightSensor): #======================================== form.startButton.pressed.connect(self.onStartMeasurement) form.stopButton.pressed.connect(self.onStopMeasurement) - form.tareButton_1.pressed.connect(self.onTareButtonClicked) + form.tareButton_1.pressed.connect(self.onTareButtonClicked_1) + form.tareButton_2.pressed.connect(self.onTareButtonClicked_2) form.bodyWeightSpinBox.valueChanged.connect(self.onBodyWeightChanged) # Action, triggered when measurement is finished @@ -183,8 +186,8 @@ def onMeasurementCallback(self): self.measFinished.trigger() else: # Read value from sensor and save it to array - valueKg_1 = self.weightSensor.getValueInKg_1() - self.tare - valueKg_2 = self.weightSensor.getValueInKg_2() - self.tare + valueKg_1 = self.weightSensor.getValueInKg_1() - self.tare_1 + valueKg_2 = self.weightSensor.getValueInKg_2() - self.tare_2 self.tareLabel_1.setText(str(np.around(valueKg_1, decimals=2)) + 'kg') self.tareLabel_2.setText(str(np.around(valueKg_2, decimals=2)) + 'kg') self.measDataKg_1[self.measCnt] = valueKg_1 @@ -235,13 +238,15 @@ def onMeasurementCallback(self): def onTareVisualization(self): self.currentWeight_1 = self.weightSensor.getValueInKg_1() self.currentWeight_2 = self.weightSensor.getValueInKg_2() - weightString_1 = str(np.around(self.currentWeight_1 - self.tare, decimals=2)) - weightString_2 = str(np.around(self.currentWeight_2 - self.tare, decimals=2)) + weightString_1 = str(np.around(self.currentWeight_1 - self.tare_1, decimals=2)) + weightString_2 = str(np.around(self.currentWeight_2 - self.tare_2, decimals=2)) self.tareLabel_1.setText(weightString_1 + 'kg') self.tareLabel_2.setText(weightString_2 + 'kg') - def onTareButtonClicked(self): - self.tare = self.currentWeight_1 + def onTareButtonClicked_1(self): + self.tare_1 = self.currentWeight_1 + def onTareButtonClicked_2(self): + self.tare_2 = self.currentWeight_2 def onWorkoutChanged(self, id): self.workoutDescriptionLabel.setText(self.workoutHandler.getWorkoutDescription(id)) From b646ab21eede819cd06a057e60eade95205a65c0 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Tue, 27 May 2025 21:44:48 +0200 Subject: [PATCH 11/17] GUIspeedtest --- ui/SpeedtestGui.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++ ui/SpeedtestGui.ui | 34 ++++++++++++++++++++++++++++++++ ui/compileUi.bat | 3 ++- 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 ui/SpeedtestGui.py create mode 100644 ui/SpeedtestGui.ui diff --git a/ui/SpeedtestGui.py b/ui/SpeedtestGui.py new file mode 100644 index 0000000..9ebae79 --- /dev/null +++ b/ui/SpeedtestGui.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'SpeedtestGui.ui' +## +## Created by: Qt User Interface Compiler version 6.6.2 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QApplication, QDialog, QHBoxLayout, QSizePolicy, + QWidget) + +from pyqtgraph import PlotWidget + +class Ui_Dialog(object): + def setupUi(self, Dialog): + if not Dialog.objectName(): + Dialog.setObjectName(u"Dialog") + Dialog.resize(499, 348) + self.horizontalLayout = QHBoxLayout(Dialog) + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.graphicsView_2 = PlotWidget(Dialog) + self.graphicsView_2.setObjectName(u"graphicsView_2") + + self.horizontalLayout.addWidget(self.graphicsView_2) + + self.graphicsView = PlotWidget(Dialog) + self.graphicsView.setObjectName(u"graphicsView") + + self.horizontalLayout.addWidget(self.graphicsView) + + + self.retranslateUi(Dialog) + + QMetaObject.connectSlotsByName(Dialog) + # setupUi + + def retranslateUi(self, Dialog): + Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Dialog", None)) + # retranslateUi + diff --git a/ui/SpeedtestGui.ui b/ui/SpeedtestGui.ui new file mode 100644 index 0000000..6758a9d --- /dev/null +++ b/ui/SpeedtestGui.ui @@ -0,0 +1,34 @@ + + + Dialog + + + + 0 + 0 + 499 + 348 + + + + Dialog + + + + + + + + + + + + + PlotWidget + QGraphicsView +
pyqtgraph
+
+
+ + +
diff --git a/ui/compileUi.bat b/ui/compileUi.bat index ec7f84a..170e3b8 100644 --- a/ui/compileUi.bat +++ b/ui/compileUi.bat @@ -2,4 +2,5 @@ pyside6-uic MeasurementGui.ui -o MeasurementGui.py pyside6-uic DataGui.ui -o DataGui.py pyside6-uic CalibrationGui.ui -o CalibrationGui.py pyside6-uic PreferencesGui.ui -o PreferencesGui.py -pyside6-uic CompareresultGui.ui -o CompareresultGui.py \ No newline at end of file +pyside6-uic CompareresultGui.ui -o CompareresultGui.py +pyside6-uic SpeedtestGui.ui -o SpeedtestGui.py \ No newline at end of file From acc55d6717af1521590b66300680ad694220e5b8 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Tue, 27 May 2025 22:01:00 +0200 Subject: [PATCH 12/17] speed test --- util/Speed_test.py | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 util/Speed_test.py diff --git a/util/Speed_test.py b/util/Speed_test.py new file mode 100644 index 0000000..13d3674 --- /dev/null +++ b/util/Speed_test.py @@ -0,0 +1,3 @@ +"1.Versuch: glätten und dann mithilfe von Steigung: nicht geklappt weil entweder zu arg geglättet oder steigung nicht hoch genug" +"2.Verscuh: nicht geglättet und mithilfe von Steigung: nicht geklappt weil steigung zu hoch ist davor" +"3.Versuch nicht geglättet und Steigung mit vielen aufeinanderfolgenden Werten" From bd3b50ea28734afa771a902f7e7dc4d1ad02e955 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Fri, 30 May 2025 14:22:46 +0200 Subject: [PATCH 13/17] speed_tst changes --- ui/MeasurementCtrl.py | 59 +++++++++++++++++++++++++++++++------------ util/Speed_test.py | 31 ++++++++++++++++++++--- 2 files changed, 71 insertions(+), 19 deletions(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 0d2ed24..4d05200 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -20,6 +20,7 @@ from PySide6.QtWidgets import QWidget from PySide6.QtGui import QAction +from PySide6.QtWidgets import QDialog import pyqtgraph as pg from psychopy import prefs @@ -32,10 +33,12 @@ import time, datetime from ui.MeasurementGui import Ui_Form +from ui.SpeedtestGui import Ui_Dialog from util.repeatedTimer import RepeatedTimer from util.params import Params from util.workouts import WorkoutHandler from util.criticalForce import computeRepetitionMean, computeCriticalForceAndWPrime, computeMaxForce +from util.Speed_test import analyse_measurements, acceleration from util.preferencesHandling import loadPreferences class MeasurementCtrl(QWidget): @@ -304,29 +307,53 @@ def computeResultAndPlot(self): pen = pg.mkPen(color=(0,180,0), width=2) self.graphicsView_1.plot([t[0],t[-1]], [cf,cf], name="CF = " + str(cf) + " %BW | W\' = " + str(W) + " %BWs", pen=pen) - ### NEU: Schnellkrafttest + + ################## speed test + workout_name = self.workoutHandler.getWorkoutName(self.selectedWorkoutId) if workout_name == 'Speed test': - #second scales - pen_2 = pg.mkPen(color=(0,0,0), width=2) - self.graphicsView_1.plot(t, measDataPercentBw_2, name="Raw Data_2", pen=pen_2) - # Beispielhafte Logik: Maxwert innerhalb einer kurzen Zeitspanne suchen + + pen = pg.mkPen(color=(0, 0, 255), width=2) + + #initalising new Window + self.speedtestWindow = QDialog(self) + self.speedtestUi = Ui_Dialog() + self.speedtestUi.setupUi(self.speedtestWindow) + self.speedtestWindow.setWindowTitle("Speedtest-Auswertung") + self.speedtestWindow.show() + + #showing new Data + self.speedtestUi.graphicsView_2.plot(t, measDataPercentBw_1, name="Raw Data 1", pen=pen) + self.speedtestUi.graphicsView.plot(t, measDataPercentBw_2, name="Raw Data 2", pen=pen) + + self.speedtestUi.graphicsView_2.addLegend().anchor(itemPos=(1,0), parentPos=(1,0), offset=(-10,10)) + self.speedtestUi.graphicsView.addLegend().anchor(itemPos=(1,0), parentPos=(1,0), offset=(-10,10)) + + # visualiziation of Max Power max_peak_1 = np.max(measDataPercentBw_1) peak_time_1 = t[np.argmax(measDataPercentBw_1)] max_peak_2 = np.max(measDataPercentBw_2) peak_time_2 = t[np.argmax(measDataPercentBw_2)] + self.speedtestUi.graphicsView_2.plot([peak_time_1], [max_peak_1], pen=None, symbol='o', symbolBrush='b', name="Peak Force_1") + self.speedtestUi.graphicsView_2.plot([t[0], t[-1]], [max_peak_1, max_peak_1], pen=pen, name="Max. Power_1 = " + str(np.around(max_peak_1, 2)) + " %BW") + self.speedtestUi.graphicsView.plot([peak_time_2], [max_peak_2], pen=None, symbol='o', symbolBrush='b', name="Peak Force_2") + self.speedtestUi.graphicsView.plot([t[0], t[-1]], [max_peak_2, max_peak_2], pen=pen, name="Max. Power_2 = " + str(np.around(max_peak_2, 2)) + " %BW") - pen = pg.mkPen(color=(0, 0, 255), width=2) - #RFD Development - #self.graphicsView_1.plot([peak_time_1], [max_peak_1], pen=None, symbol='o', symbolBrush='b', name="Peak Force_1") - #self.graphicsView_1.plot([t[0], t[-1]], [max_peak_1, max_peak_1], pen=pen, name="Max. Power_1 = " + str(np.around(max_peak_1, 2)) + " %BW") - self.graphicsView_1.plot([peak_time_1], [max_peak_1], pen=None, symbol='o', symbolBrush='b', name="Peak Force_1") - self.graphicsView_1.plot([t[0], t[-1]], [max_peak_1, max_peak_1], pen=pen, name="Max. Power_1 = " + str(np.around(max_peak_1, 2)) + " %BW") - self.graphicsView_1.plot([peak_time_2], [max_peak_2], pen=None, symbol='o', symbolBrush='b', name="Peak Force_2") - self.graphicsView_1.plot([t[0], t[-1]], [max_peak_2, max_peak_2], pen=pen, name="Max. Power_2 = " + str(np.around(max_peak_2, 2)) + " %BW") - ### ENDE: Schnellkrafttest - - # Plot maximum force + #starting point + + pen_2 = pg.mkPen(color=(0, 255, 255), width=2) + + startingpointpulling, startpointpulling_value = analyse_measurements(measDataPercentBw_1, self.fsMeas) + self.speedtestUi.graphicsView_2.plot([startingpointpulling], [startpointpulling_value], pen=None, symbol='o', symbolBrush='g', name="Start of Pulling Point" + str(np.around(startingpointpulling/self.bodyWeight, 2)) + "kg") + + #visulazation of acceleration + max_force_in_kg = max_peak_1 / self.bodyWeight + max_acceleration_1 = acceleration(max_force_in_kg, self.bodyWeight) + self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(max_acceleration_1) + "m/s²") + + ###################################### + + # Plot maximum force pen = pg.mkPen(color=(180,0,0), width=2) mf = computeMaxForce(repMean) self.graphicsView_1.plot([t[0],t[-1]], [mf,mf], name="Max. Force = " + str(mf) + " %BW", pen=pen) diff --git a/util/Speed_test.py b/util/Speed_test.py index 13d3674..2cc71f5 100644 --- a/util/Speed_test.py +++ b/util/Speed_test.py @@ -1,3 +1,28 @@ -"1.Versuch: glätten und dann mithilfe von Steigung: nicht geklappt weil entweder zu arg geglättet oder steigung nicht hoch genug" -"2.Verscuh: nicht geglättet und mithilfe von Steigung: nicht geklappt weil steigung zu hoch ist davor" -"3.Versuch nicht geglättet und Steigung mit vielen aufeinanderfolgenden Werten" +import numpy as np +import pandas as pd + +def find_monotonic_rise_start(force_data): + peak_index = np.argmax(force_data) + for i in range(peak_index - 1, 0, -1): + if force_data[i] < force_data[i - 1]: + start_index = i + break + else: + start_index = 0 + return start_index + +def analyse_measurements(force_data, sampling_rate=10): + force_data = np.array(force_data) + start_idx = find_monotonic_rise_start(force_data) + + start_time = round(start_idx / sampling_rate, 2) + start_value = round(force_data[start_idx], 2) + + return start_time, start_value + +def acceleration(force_max, bodyweight): + acceleration = (force_max * 10) * bodyweight + acceleration_round = round(acceleration, 2) + + return acceleration_round + From 4f6fcf1b6802eb79bd9e09f10444b7641f9651e4 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Mon, 9 Jun 2025 13:54:21 +0200 Subject: [PATCH 14/17] does not work!!!!! --- ui/MeasurementCtrl.py | 79 +++++++++++++++++++++++++------------- util/Speed_test.py | 73 +++++++++++++++++++++++++++++++++-- util/cedargrove_nau7802.py | 2 +- 3 files changed, 123 insertions(+), 31 deletions(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 4d05200..2d2b493 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -21,6 +21,7 @@ from PySide6.QtWidgets import QWidget from PySide6.QtGui import QAction from PySide6.QtWidgets import QDialog +from PySide6.QtCore import Qt import pyqtgraph as pg from psychopy import prefs @@ -38,7 +39,7 @@ from util.params import Params from util.workouts import WorkoutHandler from util.criticalForce import computeRepetitionMean, computeCriticalForceAndWPrime, computeMaxForce -from util.Speed_test import analyse_measurements, acceleration +from util.Speed_test import analyse_measurements, acceleration, RFD, computeSchnellkraftParameter from util.preferencesHandling import loadPreferences class MeasurementCtrl(QWidget): @@ -141,6 +142,16 @@ def __init__(self, weightSensor): self.OLD_TIME = time.time() ################################################## + #======================================= + #Initialising speed test window + #======================================= + + self.speedtestWindow = QDialog(self) + self.speedtestUi = Ui_Dialog() + self.speedtestUi.setupUi(self.speedtestWindow) + self.speedtestWindow.setWindowFlags( Qt.Window | Qt.WindowMinimizeButtonHint |Qt.WindowMaximizeButtonHint |Qt.WindowCloseButtonHint) + self.speedtestWindow.setWindowTitle("Speedtest-Auswertung") + def onStartMeasurement(self): if not self.running: self.tareTimer.stop() @@ -311,16 +322,16 @@ def computeResultAndPlot(self): ################## speed test workout_name = self.workoutHandler.getWorkoutName(self.selectedWorkoutId) + if workout_name == 'Speed test': pen = pg.mkPen(color=(0, 0, 255), width=2) - #initalising new Window - self.speedtestWindow = QDialog(self) - self.speedtestUi = Ui_Dialog() - self.speedtestUi.setupUi(self.speedtestWindow) - self.speedtestWindow.setWindowTitle("Speedtest-Auswertung") - self.speedtestWindow.show() + if not self.speedtestWindow.isVisible(): + self.speedtestWindow.show() + + self.speedtestUi.graphicsView.clear() + self.speedtestUi.graphicsView_2.clear() #showing new Data self.speedtestUi.graphicsView_2.plot(t, measDataPercentBw_1, name="Raw Data 1", pen=pen) @@ -328,29 +339,45 @@ def computeResultAndPlot(self): self.speedtestUi.graphicsView_2.addLegend().anchor(itemPos=(1,0), parentPos=(1,0), offset=(-10,10)) self.speedtestUi.graphicsView.addLegend().anchor(itemPos=(1,0), parentPos=(1,0), offset=(-10,10)) - - # visualiziation of Max Power - max_peak_1 = np.max(measDataPercentBw_1) - peak_time_1 = t[np.argmax(measDataPercentBw_1)] - max_peak_2 = np.max(measDataPercentBw_2) - peak_time_2 = t[np.argmax(measDataPercentBw_2)] - self.speedtestUi.graphicsView_2.plot([peak_time_1], [max_peak_1], pen=None, symbol='o', symbolBrush='b', name="Peak Force_1") - self.speedtestUi.graphicsView_2.plot([t[0], t[-1]], [max_peak_1, max_peak_1], pen=pen, name="Max. Power_1 = " + str(np.around(max_peak_1, 2)) + " %BW") - self.speedtestUi.graphicsView.plot([peak_time_2], [max_peak_2], pen=None, symbol='o', symbolBrush='b', name="Peak Force_2") - self.speedtestUi.graphicsView.plot([t[0], t[-1]], [max_peak_2, max_peak_2], pen=pen, name="Max. Power_2 = " + str(np.around(max_peak_2, 2)) + " %BW") - #starting point + # Speedtest parameters calculating + peaks1, tp1, starts1, tsp1, acc, rfd = computeSchnellkraftParameter(measDataPercentBw_1, self.lookupTable, self.fsMeas, self.bodyWeight) + peaks2, tp2, starts2, tsp2, _, _ = computeSchnellkraftParameter(measDataPercentBw_2, self.lookupTable, self.fsMeas, self.bodyWeight) - pen_2 = pg.mkPen(color=(0, 255, 255), width=2) + # max power + self.speedtestUi.graphicsView_2.plot(tp1, peaks1,pen=None, symbol='o', symbolBrush=(255,0,0),name="Peaks 1") + self.speedtestUi.graphicsView.plot(tp2, peaks2,pen=None, symbol='o', symbolBrush=(255,0,0),name="Peaks 2") - startingpointpulling, startpointpulling_value = analyse_measurements(measDataPercentBw_1, self.fsMeas) - self.speedtestUi.graphicsView_2.plot([startingpointpulling], [startpointpulling_value], pen=None, symbol='o', symbolBrush='g', name="Start of Pulling Point" + str(np.around(startingpointpulling/self.bodyWeight, 2)) + "kg") - + # visualiziation of Max Power in prozent von Körpergewicht + #max_peak_1 = np.max(measDataPercentBw_1) + #peak_time_1 = t[np.argmax(measDataPercentBw_1)] + #max_peak_2 = np.max(measDataPercentBw_2) + #peak_time_2 = t[np.argmax(measDataPercentBw_2)] + #self.speedtestUi.graphicsView_2.plot([peak_time_1], [max_peak_1], pen=None, symbol='o', symbolBrush='b', name="Peak Force_1 = " + str(np.around(max_peak_1, 2)) + " %BW") + #self.speedtestUi.graphicsView_2.plot([t[0], t[-1]], [max_peak_1, max_peak_1], pen=pen, name="Max. Power_1 = " + str(np.around(max_peak_1, 2)) + " %BW") + #self.speedtestUi.graphicsView.plot([peak_time_2], [max_peak_2], pen=None, symbol='o', symbolBrush='b', name="Peak Force_2 = " + str(np.around(max_peak_2, 2)) + " %BW") + #self.speedtestUi.graphicsView.plot([t[0], t[-1]], [max_peak_2, max_peak_2], pen=pen, name="Max. Power_2 = " + str(np.around(max_peak_2, 2)) + " %BW") + + #starting point + #startingpointpulling_1, startpointpulling_value_1 = analyse_measurements(measDataPercentBw_1) + #startingpointpulling_2, startpointpulling_value_2 = analyse_measurements(measDataPercentBw_2) + #self.speedtestUi.graphicsView_2.plot([startingpointpulling_1], [startpointpulling_value_1], pen=None, symbol='o', symbolBrush='g', name="Start of Pulling Point = " + str(np.around((startpointpulling_value_1), 2)) + " %BW") + #self.speedtestUi.graphicsView.plot([startingpointpulling_2], [startpointpulling_value_2], pen=None, symbol='o', symbolBrush='g', name="Start of Pulling Point = " + str(np.around(startpointpulling_value_2, 2)) + " %BW") + #visulazation of acceleration - max_force_in_kg = max_peak_1 / self.bodyWeight - max_acceleration_1 = acceleration(max_force_in_kg, self.bodyWeight) - self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(max_acceleration_1) + "m/s²") - + #max_force_in_kg_1 = (max_peak_1 / 100) * self.bodyWeight + #max_force_in_kg_2 = (max_peak_2 / 100) * self.bodyWeight + #max_acceleration_1 = acceleration(max_force_in_kg_1, self.bodyWeight) + #max_acceleration_2 = acceleration(max_force_in_kg_2, self.bodyWeight) + #self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(max_acceleration_1) + " m/s²") + #self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(max_acceleration_2) + " m/s²") + + #rfd visulazation + #rfd_1 = RFD(startingpointpulling_1, peak_time_1, max_force_in_kg_1, (startpointpulling_value_1 / 100) *self.bodyWeight) + #rfd_2 = RFD(startingpointpulling_2, peak_time_2, max_force_in_kg_2, (startpointpulling_value_2 / 100) *self.bodyWeight) + #self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(np.around(rfd_1, 2)) + " kg/s") + #self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(np.around(rfd_2)) + " kg/s") + ###################################### # Plot maximum force diff --git a/util/Speed_test.py b/util/Speed_test.py index 2cc71f5..696f007 100644 --- a/util/Speed_test.py +++ b/util/Speed_test.py @@ -1,5 +1,5 @@ import numpy as np -import pandas as pd +from ui import MeasurementCtrl def find_monotonic_rise_start(force_data): peak_index = np.argmax(force_data) @@ -11,18 +11,83 @@ def find_monotonic_rise_start(force_data): start_index = 0 return start_index -def analyse_measurements(force_data, sampling_rate=10): +def analyse_measurements(force_data, sampling_rate=80): force_data = np.array(force_data) start_idx = find_monotonic_rise_start(force_data) start_time = round(start_idx / sampling_rate, 2) start_value = round(force_data[start_idx], 2) - return start_time, start_value + return start_value, start_time def acceleration(force_max, bodyweight): - acceleration = (force_max * 10) * bodyweight + acceleration = (force_max * 10)/bodyweight acceleration_round = round(acceleration, 2) return acceleration_round +def RFD(startofpullingtimepoint, maxforcetimepoint, maxforce, startpullingpointforce): + rfd = (maxforce - startpullingpointforce) / (maxforcetimepoint - startofpullingtimepoint) + + return rfd + +def computeSchnellkraftParameter(measData, lookupTable, sampleRate, bodyweight): + #cpmoute RFD and max. acceleration + t = np.linspace(0, len(measData) / sampleRate, len(measData)) + peak_alltime = np.max(measData) + peak_timepoint_alltime = t[np.argmax(measData)] + max_force_in_kg_alltime = (peak_alltime / 100) * bodyweight + startpointpullingvalue_alltime, startpointpulling_timepoint_alltime = analyse_measurements(measData) + + + #acceleration + max_acceleration = acceleration(max_force_in_kg_alltime, bodyweight) + + #RFD + RFD = RFD(startpointpulling_timepoint_alltime, peak_timepoint_alltime, peak_alltime, startpointpullingvalue_alltime) + + #compute Startingpoints and max. peaks + lookupRsmpl = np.repeat(lookupTable, sampleRate) + + assert(len(measData) == len(lookupRsmpl)) + numSamples = len(lookupRsmpl) + + ctr = 0 + indStart = 0 + active = False + + allPeaks = [] + allPeaks_timepoint = [] + allStartingpoints = [] + allStartingpoints_timepoint = [] + + for i in range(1,numSamples): + diff = lookupRsmpl[i] - lookupRsmpl[i-1] + + if diff == 1: + # New Active Time begins + indStart = i + active = True + elif diff == -1: + # New pause begins + + #max. power + peak = np.max(measData[indStart:indStart+ctr]) + peak_timepoint = t[np.argmax(measData[indStart:indStart+ctr])] + allPeaks.append(peak) + allPeaks_timepoint.append(peak_timepoint) + + + #start pulling point + startpointpullingvalue, startpointpulling_timepoint = analyse_measurements(measData[indStart:indStart+ctr]) + allStartingpoints_timepoint.append(startpointpulling_timepoint) + allStartingpoints.append(startpointpullingvalue) + + ctr = 0 + active = False + + # Nothing changed + if active: + ctr += 1 + + return allPeaks, allPeaks_timepoint, allStartingpoints, allStartingpoints_timepoint, max_acceleration, RFD \ No newline at end of file diff --git a/util/cedargrove_nau7802.py b/util/cedargrove_nau7802.py index 1634ee6..6c1251c 100644 --- a/util/cedargrove_nau7802.py +++ b/util/cedargrove_nau7802.py @@ -116,7 +116,7 @@ def __init__(self, i2c_bus, address=0x2A, active_channels=1): self.ldo_voltage = "3V0" # 3.0-volt internal analog power (AVDD) self._pu_ldo_source = True # Internal analog power (AVDD) self.gain = 128 # X128 - self._c2_conv_rate = ConversionRate.RATE_10SPS # 10 SPS; default + self._c2_conv_rate = ConversionRate.RATE_80SPS # 10 SPS; default self._adc_chop_clock = 0x3 # 0x3 = Disable ADC chopper clock self._pga_ldo_mode = 0x0 # 0x0 = Use low ESR capacitors self._act_channels = active_channels From 5a9381342dbfe0854db1a83b91f5674fa48000b1 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Mon, 9 Jun 2025 15:22:32 +0200 Subject: [PATCH 15/17] multiple maxpowerpoints and start pullingpoints --- ui/MeasurementCtrl.py | 56 ++++++++++++++----------------------------- util/Speed_test.py | 53 +++++++++++++++++----------------------- 2 files changed, 40 insertions(+), 69 deletions(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 2d2b493..17558ae 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -319,13 +319,15 @@ def computeResultAndPlot(self): pen = pg.mkPen(color=(0,180,0), width=2) self.graphicsView_1.plot([t[0],t[-1]], [cf,cf], name="CF = " + str(cf) + " %BW | W\' = " + str(W) + " %BWs", pen=pen) - ################## speed test + #=========================== + #speed test + #=========================== workout_name = self.workoutHandler.getWorkoutName(self.selectedWorkoutId) if workout_name == 'Speed test': - pen = pg.mkPen(color=(0, 0, 255), width=2) + pen = pg.mkPen(color=(255, 255, 255), width=2) if not self.speedtestWindow.isVisible(): self.speedtestWindow.show() @@ -341,44 +343,22 @@ def computeResultAndPlot(self): self.speedtestUi.graphicsView.addLegend().anchor(itemPos=(1,0), parentPos=(1,0), offset=(-10,10)) # Speedtest parameters calculating - peaks1, tp1, starts1, tsp1, acc, rfd = computeSchnellkraftParameter(measDataPercentBw_1, self.lookupTable, self.fsMeas, self.bodyWeight) - peaks2, tp2, starts2, tsp2, _, _ = computeSchnellkraftParameter(measDataPercentBw_2, self.lookupTable, self.fsMeas, self.bodyWeight) - - # max power - self.speedtestUi.graphicsView_2.plot(tp1, peaks1,pen=None, symbol='o', symbolBrush=(255,0,0),name="Peaks 1") - self.speedtestUi.graphicsView.plot(tp2, peaks2,pen=None, symbol='o', symbolBrush=(255,0,0),name="Peaks 2") - - # visualiziation of Max Power in prozent von Körpergewicht - #max_peak_1 = np.max(measDataPercentBw_1) - #peak_time_1 = t[np.argmax(measDataPercentBw_1)] - #max_peak_2 = np.max(measDataPercentBw_2) - #peak_time_2 = t[np.argmax(measDataPercentBw_2)] - #self.speedtestUi.graphicsView_2.plot([peak_time_1], [max_peak_1], pen=None, symbol='o', symbolBrush='b', name="Peak Force_1 = " + str(np.around(max_peak_1, 2)) + " %BW") - #self.speedtestUi.graphicsView_2.plot([t[0], t[-1]], [max_peak_1, max_peak_1], pen=pen, name="Max. Power_1 = " + str(np.around(max_peak_1, 2)) + " %BW") - #self.speedtestUi.graphicsView.plot([peak_time_2], [max_peak_2], pen=None, symbol='o', symbolBrush='b', name="Peak Force_2 = " + str(np.around(max_peak_2, 2)) + " %BW") - #self.speedtestUi.graphicsView.plot([t[0], t[-1]], [max_peak_2, max_peak_2], pen=pen, name="Max. Power_2 = " + str(np.around(max_peak_2, 2)) + " %BW") - - #starting point - #startingpointpulling_1, startpointpulling_value_1 = analyse_measurements(measDataPercentBw_1) - #startingpointpulling_2, startpointpulling_value_2 = analyse_measurements(measDataPercentBw_2) - #self.speedtestUi.graphicsView_2.plot([startingpointpulling_1], [startpointpulling_value_1], pen=None, symbol='o', symbolBrush='g', name="Start of Pulling Point = " + str(np.around((startpointpulling_value_1), 2)) + " %BW") - #self.speedtestUi.graphicsView.plot([startingpointpulling_2], [startpointpulling_value_2], pen=None, symbol='o', symbolBrush='g', name="Start of Pulling Point = " + str(np.around(startpointpulling_value_2, 2)) + " %BW") - - #visulazation of acceleration - #max_force_in_kg_1 = (max_peak_1 / 100) * self.bodyWeight - #max_force_in_kg_2 = (max_peak_2 / 100) * self.bodyWeight - #max_acceleration_1 = acceleration(max_force_in_kg_1, self.bodyWeight) - #max_acceleration_2 = acceleration(max_force_in_kg_2, self.bodyWeight) - #self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(max_acceleration_1) + " m/s²") - #self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(max_acceleration_2) + " m/s²") + peaks1, tp1, starts1, tsp1, acc_1, rfd_1 = computeSchnellkraftParameter(measDataPercentBw_1, self.lookupTable, self.fsMeas, self.bodyWeight) + peaks2, tp2, starts2, tsp2, acc_2, rfd_2 = computeSchnellkraftParameter(measDataPercentBw_2, self.lookupTable, self.fsMeas, self.bodyWeight) + + self.speedtestUi.graphicsView_2.plot(tp1, peaks1,pen=None, symbol='o', symbolBrush=(0,0,255),name="max Power 1 =" + str(np.round(peaks1, 2)) + "kg") + self.speedtestUi.graphicsView.plot(tp2, peaks2,pen=None, symbol='o', symbolBrush=(0,0,255),name="max Power 2 =" + str(np.round(peaks2,2)) + "kg") + + self.speedtestUi.graphicsView_2.plot(tsp1, starts1,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 1 =" + str(np.round(starts1, 2)) + "kg") + self.speedtestUi.graphicsView.plot(tsp2, starts2,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 2 =" + str(np.round(starts2, 2)) + "kg") + + self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(acc_1) + " m/s²") + self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(acc_2) + " m/s²") - #rfd visulazation - #rfd_1 = RFD(startingpointpulling_1, peak_time_1, max_force_in_kg_1, (startpointpulling_value_1 / 100) *self.bodyWeight) - #rfd_2 = RFD(startingpointpulling_2, peak_time_2, max_force_in_kg_2, (startpointpulling_value_2 / 100) *self.bodyWeight) - #self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(np.around(rfd_1, 2)) + " kg/s") - #self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(np.around(rfd_2)) + " kg/s") + self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(np.around(rfd_1, 2)) + " kg/s") + self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(np.around(rfd_2), 2) + " kg/s") - ###################################### + #============================= # Plot maximum force pen = pg.mkPen(color=(180,0,0), width=2) diff --git a/util/Speed_test.py b/util/Speed_test.py index 696f007..857ee46 100644 --- a/util/Speed_test.py +++ b/util/Speed_test.py @@ -11,7 +11,7 @@ def find_monotonic_rise_start(force_data): start_index = 0 return start_index -def analyse_measurements(force_data, sampling_rate=80): +def analyse_measurements(force_data, sampling_rate=10): force_data = np.array(force_data) start_idx = find_monotonic_rise_start(force_data) @@ -44,50 +44,41 @@ def computeSchnellkraftParameter(measData, lookupTable, sampleRate, bodyweight): max_acceleration = acceleration(max_force_in_kg_alltime, bodyweight) #RFD - RFD = RFD(startpointpulling_timepoint_alltime, peak_timepoint_alltime, peak_alltime, startpointpullingvalue_alltime) + rfd_value = RFD(startpointpulling_timepoint_alltime, peak_timepoint_alltime, peak_alltime, startpointpullingvalue_alltime) #compute Startingpoints and max. peaks lookupRsmpl = np.repeat(lookupTable, sampleRate) - - assert(len(measData) == len(lookupRsmpl)) + assert len(measData) == len(lookupRsmpl) numSamples = len(lookupRsmpl) - - ctr = 0 + indStart = 0 - active = False allPeaks = [] allPeaks_timepoint = [] allStartingpoints = [] allStartingpoints_timepoint = [] - for i in range(1,numSamples): + for i in range(1, numSamples): diff = lookupRsmpl[i] - lookupRsmpl[i-1] if diff == 1: # New Active Time begins indStart = i - active = True - elif diff == -1: - # New pause begins - - #max. power - peak = np.max(measData[indStart:indStart+ctr]) - peak_timepoint = t[np.argmax(measData[indStart:indStart+ctr])] - allPeaks.append(peak) - allPeaks_timepoint.append(peak_timepoint) - - #start pulling point - startpointpullingvalue, startpointpulling_timepoint = analyse_measurements(measData[indStart:indStart+ctr]) - allStartingpoints_timepoint.append(startpointpulling_timepoint) - allStartingpoints.append(startpointpullingvalue) - - ctr = 0 - active = False - - # Nothing changed - if active: - ctr += 1 - - return allPeaks, allPeaks_timepoint, allStartingpoints, allStartingpoints_timepoint, max_acceleration, RFD \ No newline at end of file + elif diff == -1: + # Active Time endet → hier auswerten + segment = measData[indStart:i] + # Peak + local_peak = np.max(segment) + local_peak_idx = np.argmax(segment) + allPeaks.append(local_peak) + allPeaks_timepoint.append(t[indStart + local_peak_idx]) + + # Start-Zeitpunkt + sp_val, sp_time = analyse_measurements(segment, sampling_rate=sampleRate) + allStartingpoints.append(sp_val) + sp_time_abs = indStart/sampleRate + sp_time + allStartingpoints_timepoint.append(round(sp_time_abs, 2)) + + return allPeaks, allPeaks_timepoint, allStartingpoints, \ + allStartingpoints_timepoint, max_acceleration, rfd_value From ec65f93f8e57884724ac8945eb88a6451dfe1b6e Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Mon, 9 Jun 2025 15:41:18 +0200 Subject: [PATCH 16/17] new MeasCtrl --- ui/MeasurementCtrl.py | 12 ++++++------ util/Speed_test.py | 2 +- util/cedargrove_nau7802.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 17558ae..dd758dd 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -346,17 +346,17 @@ def computeResultAndPlot(self): peaks1, tp1, starts1, tsp1, acc_1, rfd_1 = computeSchnellkraftParameter(measDataPercentBw_1, self.lookupTable, self.fsMeas, self.bodyWeight) peaks2, tp2, starts2, tsp2, acc_2, rfd_2 = computeSchnellkraftParameter(measDataPercentBw_2, self.lookupTable, self.fsMeas, self.bodyWeight) - self.speedtestUi.graphicsView_2.plot(tp1, peaks1,pen=None, symbol='o', symbolBrush=(0,0,255),name="max Power 1 =" + str(np.round(peaks1, 2)) + "kg") - self.speedtestUi.graphicsView.plot(tp2, peaks2,pen=None, symbol='o', symbolBrush=(0,0,255),name="max Power 2 =" + str(np.round(peaks2,2)) + "kg") + self.speedtestUi.graphicsView_2.plot(tp1, peaks1,pen=None, symbol='o', symbolBrush=(0,0,255),name="max Power 1 ="+ str(np.round(peaks1, 2)) + " kg") + self.speedtestUi.graphicsView.plot(tp2, peaks2,pen=None, symbol='o', symbolBrush=(0,0,255),name="max Power 2 ="+ str(np.round(peaks2,2)) + " kg") - self.speedtestUi.graphicsView_2.plot(tsp1, starts1,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 1 =" + str(np.round(starts1, 2)) + "kg") - self.speedtestUi.graphicsView.plot(tsp2, starts2,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 2 =" + str(np.round(starts2, 2)) + "kg") + self.speedtestUi.graphicsView_2.plot(tsp1, starts1,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 1 ="+ str(np.round(starts1, 2)) + " kg") + self.speedtestUi.graphicsView.plot(tsp2, starts2,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 2 ="+ str(np.round(starts2, 2)) + " kg") self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(acc_1) + " m/s²") self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(acc_2) + " m/s²") - self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(np.around(rfd_1, 2)) + " kg/s") - self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(np.around(rfd_2), 2) + " kg/s") + self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(round(rfd_1, 2)) + " kg/s") + self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="RFD = " + str(round(rfd_2, 2)) + " kg/s") #============================= diff --git a/util/Speed_test.py b/util/Speed_test.py index 857ee46..b58fc8a 100644 --- a/util/Speed_test.py +++ b/util/Speed_test.py @@ -78,7 +78,7 @@ def computeSchnellkraftParameter(measData, lookupTable, sampleRate, bodyweight): sp_val, sp_time = analyse_measurements(segment, sampling_rate=sampleRate) allStartingpoints.append(sp_val) sp_time_abs = indStart/sampleRate + sp_time - allStartingpoints_timepoint.append(round(sp_time_abs, 2)) + allStartingpoints_timepoint.append(sp_time_abs) return allPeaks, allPeaks_timepoint, allStartingpoints, \ allStartingpoints_timepoint, max_acceleration, rfd_value diff --git a/util/cedargrove_nau7802.py b/util/cedargrove_nau7802.py index 6c1251c..9fe2d59 100644 --- a/util/cedargrove_nau7802.py +++ b/util/cedargrove_nau7802.py @@ -97,7 +97,7 @@ class CalibrationMode: INTERNAL = 0x0 # Offset Calibration Internal; _CTRL2[1:0] = 0 (chip default) OFFSET = 0x2 # Offset Calibration System; _CTRL2[1:0] = 2 - GAIN = 0x3 # Gain Calibration System; _CTRL2[1:0] = 3 + GAIN = 0x3 # Gain Calibration System; _CTRL2[1:0] = 3 class NAU7802: @@ -116,7 +116,7 @@ def __init__(self, i2c_bus, address=0x2A, active_channels=1): self.ldo_voltage = "3V0" # 3.0-volt internal analog power (AVDD) self._pu_ldo_source = True # Internal analog power (AVDD) self.gain = 128 # X128 - self._c2_conv_rate = ConversionRate.RATE_80SPS # 10 SPS; default + self._c2_conv_rate = ConversionRate.RATE_10SPS # 10 SPS; default self._adc_chop_clock = 0x3 # 0x3 = Disable ADC chopper clock self._pga_ldo_mode = 0x0 # 0x0 = Use low ESR capacitors self._act_channels = active_channels From a8cc28c303560d7e5d3ec1265ea87b8cf26decc7 Mon Sep 17 00:00:00 2001 From: threedegreesofseperation Date: Wed, 25 Jun 2025 15:13:18 +0200 Subject: [PATCH 17/17] . --- ui/MeasurementCtrl.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index dd758dd..c50734b 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -332,7 +332,7 @@ def computeResultAndPlot(self): if not self.speedtestWindow.isVisible(): self.speedtestWindow.show() - self.speedtestUi.graphicsView.clear() + self.speedtestUi.graphicsView.clear() self.speedtestUi.graphicsView_2.clear() #showing new Data @@ -349,8 +349,8 @@ def computeResultAndPlot(self): self.speedtestUi.graphicsView_2.plot(tp1, peaks1,pen=None, symbol='o', symbolBrush=(0,0,255),name="max Power 1 ="+ str(np.round(peaks1, 2)) + " kg") self.speedtestUi.graphicsView.plot(tp2, peaks2,pen=None, symbol='o', symbolBrush=(0,0,255),name="max Power 2 ="+ str(np.round(peaks2,2)) + " kg") - self.speedtestUi.graphicsView_2.plot(tsp1, starts1,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 1 ="+ str(np.round(starts1, 2)) + " kg") - self.speedtestUi.graphicsView.plot(tsp2, starts2,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 2 ="+ str(np.round(starts2, 2)) + " kg") + self.speedtestUi.graphicsView_2.plot(tsp1, starts1,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 1 ="+ str(np.round(starts1, 2)) + " %") + self.speedtestUi.graphicsView.plot(tsp2, starts2,pen=None, symbol='o', symbolBrush=(0,255,0),name="Start pullingpoint 2 ="+ str(np.round(starts2, 2)) + " %") self.speedtestUi.graphicsView_2.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(acc_1) + " m/s²") self.speedtestUi.graphicsView.plot([0], [0], pen=None, symbol=None, name="Max. Acceleration = " + str(acc_2) + " m/s²")