diff --git a/src/main/java/com/puchdyno/DynoGUI.java b/src/main/java/com/puchdyno/DynoGUI.java index eddf250..3be65b7 100644 --- a/src/main/java/com/puchdyno/DynoGUI.java +++ b/src/main/java/com/puchdyno/DynoGUI.java @@ -10,6 +10,8 @@ import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.*; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.xy.*; +import org.jfree.chart.renderer.xy.XYSplineRenderer; +import java.awt.BasicStroke; public class DynoGUI extends JFrame { private final JLabel leistungLabel; @@ -156,12 +158,14 @@ public class DynoGUI extends JFrame { xAxis.setLabelFont(new Font("SansSerif", Font.BOLD, 14)); // Renderers - XYLineAndShapeRenderer powerRenderer = new XYLineAndShapeRenderer(true, false); + org.jfree.chart.renderer.xy.XYSplineRenderer powerRenderer = new org.jfree.chart.renderer.xy.XYSplineRenderer(); powerRenderer.setSeriesPaint(0, new Color(220, 50, 47)); // Red + powerRenderer.setSeriesStroke(0, new BasicStroke(2f)); plot.setRenderer(0, powerRenderer); - XYLineAndShapeRenderer torqueRenderer = new XYLineAndShapeRenderer(true, false); + org.jfree.chart.renderer.xy.XYSplineRenderer torqueRenderer = new org.jfree.chart.renderer.xy.XYSplineRenderer(); torqueRenderer.setSeriesPaint(0, new Color(38, 139, 210)); // Blue + torqueRenderer.setSeriesStroke(0, new BasicStroke(2f)); plot.setRenderer(1, torqueRenderer); XYLineAndShapeRenderer effRenderer = new XYLineAndShapeRenderer(false, true); @@ -196,7 +200,35 @@ public class DynoGUI extends JFrame { leistungLabel.setText(String.format("Leistung: %.2f PS", leistung)); drehmomentLabel.setText(String.format("Drehmoment: %.2f Nm", drehmoment)); - // update max hold values + // keine Plot-Aktualisierung hier – siehe addPlotData() + } + + public void resetChart() { + powerSeries.clear(); + torqueSeries.clear(); + efficiencySeries.clear(); + } + + public void resetMaxHold() { + maxLeistung = 0.0; + maxDrehmoment = 0.0; + maxLeistungRpm = 0.0; + maxLeistungNmAtHp = 0.0; + maxDrehmomentRpm = 0.0; + maxDrehmomentPsAtNm = 0.0; + efficiencySeries.clear(); + maxLeistungLabel.setText("Max Leistung: 0.00 PS"); + maxDrehmomentLabel.setText("Max Drehmoment: 0.00 Nm"); + } + + public JFreeChart getChart() { + return chartPanel.getChart(); + } + + /** + * Fügt Datenpunkte in den Diagrammen hinzu. Nur während aktiver Messung aufrufen. + */ + public void addPlotData(double leistung, double drehmoment, double rpm) { boolean effUpdated = false; if (leistung > maxLeistung) { maxLeistung = leistung; @@ -220,30 +252,13 @@ public class DynoGUI extends JFrame { } if (maxDrehmoment > 0) { double effNm = maxDrehmomentPsAtNm == 0 ? 0.0 : maxDrehmomentPsAtNm / maxDrehmoment; - // avoid duplicate point if same rpm - if (maxDrehmomentRpm != maxLeistungRpm) + if (maxDrehmomentRpm != maxLeistungRpm) { efficiencySeries.add(maxDrehmomentRpm, effNm); + } } } powerSeries.add(rpm, leistung); torqueSeries.add(rpm, drehmoment); } - - public void resetChart() { - powerSeries.clear(); - torqueSeries.clear(); - efficiencySeries.clear(); - } - - public void resetMaxHold() { - maxLeistung = 0.0; - maxDrehmoment = 0.0; - maxLeistungLabel.setText("Max Leistung: 0.00 PS"); - maxDrehmomentLabel.setText("Max Drehmoment: 0.00 Nm"); - } - - public JFreeChart getChart() { - return chartPanel.getChart(); - } } diff --git a/src/main/java/com/puchdyno/Main.java b/src/main/java/com/puchdyno/Main.java index 1dea028..b960574 100644 --- a/src/main/java/com/puchdyno/Main.java +++ b/src/main/java/com/puchdyno/Main.java @@ -42,6 +42,11 @@ public class Main { private static CSVLogger csvLogger; private static boolean measurementActive = false; + private static double peakRpmDuringRun = 0.0; + private static int belowThresholdCounter = 0; + private static final int BELOW_THRESHOLD_LIMIT = 20; // 20 * 10ms = 200ms + private static final double RPM_DROP_FACTOR = 0.3; // 30% of peak + public static void main(String[] args) { SwingUtilities.invokeLater(() -> { dynoGUI = new DynoGUI(); @@ -119,14 +124,22 @@ public class Main { } dynoGUI.resetChart(); + measurementActive = true; lastTimestamp = 0; lastOmega = 0.0; + peakRpmDuringRun = 0.0; + belowThresholdCounter = 0; + + if (csvLogger != null) { try { csvLogger.close(); } catch (Exception ex) {} } + try { csvLogger = new CSVLogger(new java.io.File("logs")); } catch(Exception ex) { csvLogger = null; } + + final long simStartTime = System.currentTimeMillis(); testDataExecutor = Executors.newSingleThreadScheduledExecutor(); testDataExecutor.scheduleAtFixedRate(() -> { // Simulate a realistic dyno run pattern long currentTime = System.currentTimeMillis(); - double elapsedSeconds = (currentTime - lastTimestamp) / 1000.0; + double elapsedSeconds = (currentTime - simStartTime) / 1000.0; // Simulate acceleration, hold, then deceleration double simulatedRpm; @@ -158,12 +171,14 @@ public class Main { testDataExecutor.shutdownNow(); testDataExecutor = null; SwingUtilities.invokeLater(() -> { - dynoGUI.updateWerte(0, 0, 0); // Reset gauges + dynoGUI.updateWerte(0, 0, 0); if (csvLogger != null) { try { csvLogger.close(); } catch (Exception ex) { ex.printStackTrace(); } csvLogger = null; } + showPrintableChart(); }); + measurementActive = false; } } @@ -310,8 +325,26 @@ public class Main { double drehmoment = leistungBerechner.berechneDrehmoment(lastOmega, currentOmega, deltaTime); double leistung = leistungBerechner.berechneLeistung(drehmoment, currentOmega); + if (measurementActive) { + if (rpm > peakRpmDuringRun) { + peakRpmDuringRun = rpm; + } + if (peakRpmDuringRun > 0 && rpm < peakRpmDuringRun * RPM_DROP_FACTOR) { + belowThresholdCounter++; + } else { + belowThresholdCounter = 0; + } + + if (belowThresholdCounter >= BELOW_THRESHOLD_LIMIT) { + SwingUtilities.invokeLater(() -> stopMeasurement()); + } + } + SwingUtilities.invokeLater(() -> { dynoGUI.updateWerte(leistung, drehmoment, rpm); + if (measurementActive) { + dynoGUI.addPlotData(leistung, drehmoment, rpm); + } }); lastTimestamp = currentTimestamp; @@ -337,8 +370,25 @@ public class Main { double drehmoment = leistungBerechner.berechneDrehmoment(lastOmega, currentOmega, forcedDeltaTime); double leistung = leistungBerechner.berechneLeistung(drehmoment, currentOmega); + if (measurementActive) { + if (rpm > peakRpmDuringRun) { + peakRpmDuringRun = rpm; + } + if (peakRpmDuringRun > 0 && rpm < peakRpmDuringRun * RPM_DROP_FACTOR) { + belowThresholdCounter++; + } else { + belowThresholdCounter = 0; + } + if (belowThresholdCounter >= BELOW_THRESHOLD_LIMIT) { + SwingUtilities.invokeLater(() -> stopMeasurement()); + } + } + SwingUtilities.invokeLater(() -> { dynoGUI.updateWerte(leistung, drehmoment, rpm); + if (measurementActive) { + dynoGUI.addPlotData(leistung, drehmoment, rpm); + } }); lastOmega = currentOmega; @@ -487,6 +537,8 @@ public class Main { csvLogger = null; System.err.println("CSV Logger konnte nicht erstellt werden: " + ex.getMessage()); } + peakRpmDuringRun = 0.0; + belowThresholdCounter = 0; } private static void stopMeasurement() { @@ -499,6 +551,10 @@ public class Main { try { csvLogger.close(); } catch (Exception ex) { ex.printStackTrace(); } csvLogger = null; } + // Snapshot chart for printing + showPrintableChart(); + peakRpmDuringRun = 0.0; + belowThresholdCounter = 0; JOptionPane.showMessageDialog(null, "Messung gestoppt.", "Info", JOptionPane.INFORMATION_MESSAGE); } } \ No newline at end of file