Java tutorial
/* * Open-Source tuning tools * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package com.vgi.mafscaling; import java.awt.Color; import java.awt.Cursor; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.text.DecimalFormat; import java.text.Format; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map.Entry; import java.util.ResourceBundle; import javax.swing.JCheckBox; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.border.LineBorder; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableColumnModel; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumn; import org.apache.log4j.Logger; import org.jfree.chart.plot.XYPlot; import org.jfree.data.function.Function2D; import org.jfree.data.function.LineFunction2D; import org.jfree.data.statistics.Regression; import org.jfree.data.xy.XYSeries; public class ClosedLoop extends AMafScaling { private static final long serialVersionUID = 2988105467764335997L; private static final Logger logger = Logger.getLogger(ClosedLoop.class); private static final String SaveDataFileHeader = "[closed_loop run data]"; private static final String Afr1TableName = "AFR Average"; private static final String Afr2TableName = "AFR Cell Hit Count"; private static final String Y2AxisName = "Total Correction (%)"; private static final String dvdtAxisName = "dV / dt"; private static final String iatAxisName = "IAT"; private static final String trpmAxisName = "Trims / Rpm"; private static final String mnmdAxisName = "Mean / Mode"; private static final String mnmd2AxisName = "Trims / MafV"; private static final String timeAxisName = "Time"; private static final String rpmAxisName = "RPM"; private static final String totalCorrectionDataName = "Total Correction"; private static final int ColumnCount = 9; private static final int AfrTableColumnCount = 15; private static final int AfrTableRowCount = 25; private static final int LogDataRowCount = 200; private int clValue = Config.getClOlStatusValue(); private int minCellHitCount = Config.getCLMinCellHitCount(); private double afrMin = Config.getAfrMinimumValue(); private double afrMax = Config.getAfrMaximumValue(); private double minLoad = Config.getLoadMinimumValue(); private double maxDvDt = Config.getDvDtMaximumValue(); private double maxMafV = Config.getMafVMaximumValue(); private double maxIat = Config.getIatMaximumValue(); private int logClOlStatusColIdx = -1; private int logAfLearningColIdx = -1; private int logAfCorrectionColIdx = -1; private int logAfrColIdx = -1; private int logRpmColIdx = -1; private int logLoadColIdx = -1; private int logTimeColIdx = -1; private int logMafvColIdx = -1; private int logIatColIdx = -1; private JTable logDataTable = null; private JTable afr1Table = null; private JTable afr2Table = null; private JCheckBox checkBoxDvdtData = null; private JCheckBox checkBoxIatData = null; private JCheckBox checkBoxTrpmData = null; private JCheckBox checkBoxMnmdData = null; private ArrayList<Double> trimArray = new ArrayList<Double>(); private ArrayList<Double> timeArray = new ArrayList<Double>(); private ArrayList<Double> iatArray = new ArrayList<Double>(); private ArrayList<Double> dvdtArray = new ArrayList<Double>(); private ArrayList<Double> correctionMeanArray = new ArrayList<Double>(); private ArrayList<Double> correctionModeArray = new ArrayList<Double>(); public ClosedLoop(int tabPlacement, PrimaryOpenLoopFuelingTable table, MafCompare comparer) { super(tabPlacement, table, comparer); runData = new XYSeries(totalCorrectionDataName); initialize(); } ////////////////////////////////////////////////////////////////////////////////////// // DATA TAB ////////////////////////////////////////////////////////////////////////////////////// protected void createRunPanel(JPanel dataPanel) { JPanel runPanel = new JPanel(); GridBagConstraints gbc_runPanel = new GridBagConstraints(); gbc_runPanel.fill = GridBagConstraints.BOTH; gbc_runPanel.weightx = 1.0; gbc_runPanel.weighty = 1.0; gbc_runPanel.gridx = 0; gbc_runPanel.gridy = 3; dataPanel.add(runPanel, gbc_runPanel); GridBagLayout gbl_runPanel = new GridBagLayout(); gbl_runPanel.columnWidths = new int[] { 0, 0 }; gbl_runPanel.rowHeights = new int[] { 0 }; gbl_runPanel.columnWeights = new double[] { 0.0, 0.0 }; gbl_runPanel.rowWeights = new double[] { 0.0 }; runPanel.setLayout(gbl_runPanel); JScrollPane dataScrollPane = new JScrollPane(); createLogDataTable(dataScrollPane); GridBagConstraints gbc_dataScrollPane = new GridBagConstraints(); gbc_dataScrollPane.fill = GridBagConstraints.BOTH; gbc_dataScrollPane.ipadx = ColumnWidth * ColumnCount; gbc_dataScrollPane.weighty = 1.0; gbc_dataScrollPane.gridx = 0; gbc_dataScrollPane.gridy = 0; runPanel.add(dataScrollPane, gbc_dataScrollPane); JScrollPane aprScrollPane = new JScrollPane(); createAfrDataTables(aprScrollPane); GridBagConstraints gbc_aprScrollPane = new GridBagConstraints(); gbc_aprScrollPane.weightx = 1.0; gbc_aprScrollPane.weighty = 1.0; gbc_aprScrollPane.anchor = GridBagConstraints.PAGE_START; gbc_aprScrollPane.fill = GridBagConstraints.BOTH; gbc_aprScrollPane.gridx = 1; gbc_aprScrollPane.gridy = 0; runPanel.add(aprScrollPane, gbc_aprScrollPane); } private void createLogDataTable(JScrollPane dataScrollPane) { JPanel dataRunPanel = new JPanel(); dataScrollPane.setViewportView(dataRunPanel); GridBagLayout gbl_dataRunPanel = new GridBagLayout(); gbl_dataRunPanel.columnWidths = new int[] { 0 }; gbl_dataRunPanel.rowHeights = new int[] { 0 }; gbl_dataRunPanel.columnWeights = new double[] { 0.0 }; gbl_dataRunPanel.rowWeights = new double[] { 0.0 }; dataRunPanel.setLayout(gbl_dataRunPanel); logDataTable = new JTable(); logDataTable.getTableHeader().setReorderingAllowed(false); logDataTable.setModel(new DefaultTableModel(LogDataRowCount, ColumnCount)); logDataTable.setColumnSelectionAllowed(true); logDataTable.setCellSelectionEnabled(true); logDataTable.setBorder(new LineBorder(new Color(0, 0, 0))); logDataTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); logDataTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); logDataTable.getColumnModel().getColumn(0).setHeaderValue("Time"); logDataTable.getColumnModel().getColumn(1).setHeaderValue("Load"); logDataTable.getColumnModel().getColumn(2).setHeaderValue("RPM"); logDataTable.getColumnModel().getColumn(3).setHeaderValue("MafV"); logDataTable.getColumnModel().getColumn(4).setHeaderValue("AFR"); logDataTable.getColumnModel().getColumn(5).setHeaderValue("STFT"); logDataTable.getColumnModel().getColumn(6).setHeaderValue("LTFT"); logDataTable.getColumnModel().getColumn(7).setHeaderValue("dV/dt"); logDataTable.getColumnModel().getColumn(8).setHeaderValue("IAT"); Utils.initializeTable(logDataTable, ColumnWidth); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(0, 0, 0, 0); gbc.anchor = GridBagConstraints.PAGE_START; gbc.gridx = 0; gbc.gridy = 0; dataRunPanel.add(logDataTable.getTableHeader(), gbc); gbc.gridy = 1; dataRunPanel.add(logDataTable, gbc); excelAdapter.addTable(logDataTable, true, false); } private void createAfrDataTables(JScrollPane aprScrollPane) { JPanel aprRunPanel = new JPanel(); aprScrollPane.setViewportView(aprRunPanel); GridBagLayout gbl_aprRunPanel = new GridBagLayout(); gbl_aprRunPanel.columnWidths = new int[] { 0, 0 }; gbl_aprRunPanel.rowHeights = new int[] { 0, 0, 0, 0, 0 }; gbl_aprRunPanel.columnWeights = new double[] { 0.0, 1.0 }; gbl_aprRunPanel.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 1.0 }; aprRunPanel.setLayout(gbl_aprRunPanel); afr1Table = createAfrDataTable(aprRunPanel, Afr1TableName, 0); afr2Table = createAfrDataTable(aprRunPanel, Afr2TableName, 2); } private JTable createAfrDataTable(JPanel panel, String tableName, int gridy) { final JTable afrTable = new JTable() { private static final long serialVersionUID = 6526901361175099297L; public boolean isCellEditable(int row, int column) { return false; }; }; DefaultTableColumnModel afrModel = new DefaultTableColumnModel(); final TableColumn afrColumn = new TableColumn(0, 250); afrColumn.setHeaderValue(tableName); afrModel.addColumn(afrColumn); JTableHeader lblAfrTableName = afrTable.getTableHeader(); lblAfrTableName.setColumnModel(afrModel); lblAfrTableName.setReorderingAllowed(false); DefaultTableCellRenderer headerRenderer = (DefaultTableCellRenderer) lblAfrTableName.getDefaultRenderer(); headerRenderer.setHorizontalAlignment(SwingConstants.LEFT); GridBagConstraints gbc_lblAfrTableName = new GridBagConstraints(); gbc_lblAfrTableName.insets = new Insets((gridy == 0 ? 0 : 5), 0, 0, 0); gbc_lblAfrTableName.anchor = GridBagConstraints.PAGE_START; gbc_lblAfrTableName.fill = GridBagConstraints.HORIZONTAL; gbc_lblAfrTableName.gridx = 0; gbc_lblAfrTableName.gridy = gridy; panel.add(lblAfrTableName, gbc_lblAfrTableName); afrTable.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { afrColumn.setWidth(afrTable.getWidth()); } }); afrTable.getTableHeader().setReorderingAllowed(false); afrTable.setColumnSelectionAllowed(true); afrTable.setCellSelectionEnabled(true); afrTable.setBorder(new LineBorder(new Color(0, 0, 0))); afrTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); afrTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); afrTable.setModel(new DefaultTableModel(AfrTableRowCount, AfrTableColumnCount)); Utils.initializeTable(afrTable, ColumnWidth); if (tableName.equals(Afr1TableName)) { Format[][] formatMatrix = { { new DecimalFormat("#"), new DecimalFormat("0.00") } }; NumberFormatRenderer renderer = (NumberFormatRenderer) afrTable.getDefaultRenderer(Object.class); renderer.setFormats(formatMatrix); } else if (tableName.equals(Afr2TableName)) { Format[][] formatMatrix = { { new DecimalFormat("#"), new DecimalFormat("0.00") }, { new DecimalFormat("#"), new DecimalFormat("#") } }; NumberFormatRenderer renderer = (NumberFormatRenderer) afrTable.getDefaultRenderer(Object.class); renderer.setFormats(formatMatrix); } GridBagConstraints gbc_afrTable = new GridBagConstraints(); gbc_afrTable.insets = new Insets(0, 0, 0, 0); gbc_afrTable.anchor = GridBagConstraints.PAGE_START; gbc_afrTable.gridx = 0; gbc_afrTable.gridy = gridy + 1; panel.add(afrTable, gbc_afrTable); excelAdapter.addTable(afrTable, true, false); return afrTable; } ////////////////////////////////////////////////////////////////////////////////////// // CREATE CHART TAB ////////////////////////////////////////////////////////////////////////////////////// protected void createGraghTab() { JPanel cntlPanel = new JPanel(); JPanel plotPanel = createGraphPlotPanel(cntlPanel); add(plotPanel, "<html><div style='text-align: center;'>C<br>h<br>a<br>r<br>t</div></html>"); GridBagLayout gbl_cntlPanel = new GridBagLayout(); gbl_cntlPanel.columnWidths = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; gbl_cntlPanel.rowHeights = new int[] { 0, 0 }; gbl_cntlPanel.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE }; gbl_cntlPanel.rowWeights = new double[] { 0 }; cntlPanel.setLayout(gbl_cntlPanel); GridBagConstraints gbc_check = new GridBagConstraints(); gbc_check.insets = insets2; gbc_check.gridx = 0; gbc_check.gridy = 0; checkBoxDvdtData = new JCheckBox("dV/dt"); checkBoxDvdtData.setActionCommand("dvdt"); checkBoxDvdtData.addActionListener(this); cntlPanel.add(checkBoxDvdtData, gbc_check); gbc_check.gridx++; checkBoxIatData = new JCheckBox("IAT"); checkBoxIatData.setActionCommand("iat"); checkBoxIatData.addActionListener(this); cntlPanel.add(checkBoxIatData, gbc_check); gbc_check.gridx++; checkBoxTrpmData = new JCheckBox("Trims/RPM"); checkBoxTrpmData.setActionCommand("trpm"); checkBoxTrpmData.addActionListener(this); cntlPanel.add(checkBoxTrpmData, gbc_check); gbc_check.gridx++; checkBoxMnmdData = new JCheckBox("Mean/Mode"); checkBoxMnmdData.setActionCommand("mnmd"); checkBoxMnmdData.addActionListener(this); cntlPanel.add(checkBoxMnmdData, gbc_check); gbc_check.gridx++; checkBoxRunData = new JCheckBox("Total Correction"); checkBoxRunData.setActionCommand("corrdata"); checkBoxRunData.addActionListener(this); cntlPanel.add(checkBoxRunData, gbc_check); gbc_check.gridx++; createGraphCommonControls(cntlPanel, gbc_check.gridx); createChart(plotPanel, Y2AxisName); createMafSmoothingPanel(plotPanel); } ////////////////////////////////////////////////////////////////////////////////////// // COMMOMN ACTIONS RELATED FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////// @Override public void actionPerformed(ActionEvent e) { if (checkActionPerformed(e)) return; if ("dvdt".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { clearNotRunDataCheckboxes(); clearRunDataCheckboxes(); if (plotDvdtData()) checkBox.setSelected(true); } else runData.clear(); setRanges(); } else if ("iat".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { clearNotRunDataCheckboxes(); clearRunDataCheckboxes(); if (plotIatData()) checkBox.setSelected(true); } else runData.clear(); setRanges(); } else if ("trpm".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { clearNotRunDataCheckboxes(); clearRunDataCheckboxes(); if (plotTrimRpmData()) checkBox.setSelected(true); } else { runData.clear(); currMafData.clear(); } setRanges(); } else if ("mnmd".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { clearNotRunDataCheckboxes(); clearRunDataCheckboxes(); if (plotMeanModeData()) checkBox.setSelected(true); } else { currMafData.clear(); corrMafData.clear(); runData.clear(); } setRanges(); } else if ("corrdata".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { clearRunDataCheckboxes(); if (!plotCorrectionData()) checkBox.setSelected(false); } else runData.clear(); setRanges(); } else if ("current".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { clearRunDataCheckboxes(); if (!plotCurrentMafData()) checkBox.setSelected(false); } else currMafData.clear(); setRanges(); } else if ("corrected".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { clearRunDataCheckboxes(); if (!setCorrectedMafData()) checkBox.setSelected(false); } else corrMafData.clear(); setRanges(); } else if ("smoothed".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { clearRunDataCheckboxes(); if (!setSmoothedMafData()) checkBox.setSelected(false); } else smoothMafData.clear(); setRanges(); } else if ("smoothing".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) enableSmoothingView(true); else enableSmoothingView(false); setRanges(); } } private void clearRunDataCheckboxes() { if (checkBoxDvdtData.isSelected()) { checkBoxDvdtData.setSelected(false); runData.clear(); } if (checkBoxIatData.isSelected()) { checkBoxIatData.setSelected(false); runData.clear(); } if (checkBoxTrpmData.isSelected()) { checkBoxTrpmData.setSelected(false); currMafData.clear(); runData.clear(); } if (checkBoxMnmdData.isSelected()) { checkBoxMnmdData.setSelected(false); currMafData.clear(); corrMafData.clear(); runData.clear(); } } protected void clearRunTables() { clearLogDataTables(); clearAfrDataTables(); } private void clearLogDataTables() { setCursor(new Cursor(Cursor.WAIT_CURSOR)); try { while (LogDataRowCount < logDataTable.getRowCount()) Utils.removeRow(LogDataRowCount, logDataTable); Utils.clearTable(logDataTable); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } } private void clearAfrDataTables() { setCursor(new Cursor(Cursor.WAIT_CURSOR)); try { clearAfrDataTable(afr1Table); clearAfrDataTable(afr2Table); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } } private void clearAfrDataTable(JTable table) { while (AfrTableRowCount < table.getRowCount()) Utils.removeRow(AfrTableRowCount, table); while (AfrTableColumnCount < table.getColumnCount()) Utils.removeColumn(AfrTableColumnCount, table); Utils.clearTable(table); } protected void clearData() { super.clearData(); trimArray.clear(); timeArray.clear(); iatArray.clear(); dvdtArray.clear(); Utils.clearTable(afr1Table); Utils.clearTable(afr2Table); } protected void clearChartCheckBoxes() { super.clearChartCheckBoxes(); checkBoxDvdtData.setSelected(false); checkBoxIatData.setSelected(false); } protected void calculateMafScaling() { if (!polfTable.validate()) return; setCursor(new Cursor(Cursor.WAIT_CURSOR)); try { clearData(); clearChartData(); clearChartCheckBoxes(); if (!getMafTableData(voltArray, gsArray)) return; calculateCorrectedGS(); setCorrectedMafData(); smoothGsArray.addAll(gsCorrected); checkBoxCorrectedMaf.setSelected(true); setXYTable(mafSmoothingTable, voltArray, smoothGsArray); setRanges(); } catch (Exception e) { e.printStackTrace(); logger.error(e); JOptionPane.showMessageDialog(null, "Error: " + e, "Error", JOptionPane.ERROR_MESSAGE); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } } private void calculateCorrectedGS() { double time; double load; double rpm; double dvdt; double afr; double mafv; double stft; double ltft; double iat; double corr; double val1; double val2; String timeStr; String loadStr; String rpmStr; String mafvStr; String afrStr; String stftStr; String ltftStr; String dvdtStr; String iatStr; int closestMafIdx; int closestRmpIdx; int closestLoadIdx; int i; String tableName = "Log Data"; ArrayList<Integer> temp = new ArrayList<Integer>(gsArray.size()); correctionMeanArray = new ArrayList<Double>(gsArray.size()); correctionModeArray = new ArrayList<Double>(gsArray.size()); ArrayList<HashMap<Double, Integer>> modeCalcArray = new ArrayList<HashMap<Double, Integer>>(); for (i = 0; i < gsArray.size(); ++i) { temp.add(0); correctionMeanArray.add(0.0); correctionModeArray.add(0.0); modeCalcArray.add(new HashMap<Double, Integer>()); } ArrayList<Double> afrRpmArray = new ArrayList<Double>(); for (i = 1; i < polfTable.getRowCount(); ++i) { afrRpmArray.add(Double.valueOf(polfTable.getValueAt(i, 0).toString())); Utils.ensureRowCount(i + 1, afr1Table); Utils.ensureRowCount(i + 1, afr2Table); afr1Table.setValueAt(polfTable.getValueAt(i, 0), i, 0); afr2Table.setValueAt(polfTable.getValueAt(i, 0), i, 0); } ArrayList<Double> afrLoadArray = new ArrayList<Double>(); for (i = 1; i < polfTable.getColumnCount(); ++i) { afrLoadArray.add(Double.valueOf(polfTable.getValueAt(0, i).toString())); Utils.ensureColumnCount(i + 1, afr1Table); Utils.ensureColumnCount(i + 1, afr2Table); afr1Table.setValueAt(polfTable.getValueAt(0, i), 0, i); afr2Table.setValueAt(polfTable.getValueAt(0, i), 0, i); } Integer val; HashMap<Double, Integer> modeCountMap; for (i = 0; i < logDataTable.getRowCount(); ++i) { timeStr = logDataTable.getValueAt(i, 0).toString(); loadStr = logDataTable.getValueAt(i, 1).toString(); rpmStr = logDataTable.getValueAt(i, 2).toString(); mafvStr = logDataTable.getValueAt(i, 3).toString(); afrStr = logDataTable.getValueAt(i, 4).toString(); stftStr = logDataTable.getValueAt(i, 5).toString(); ltftStr = logDataTable.getValueAt(i, 6).toString(); dvdtStr = logDataTable.getValueAt(i, 7).toString(); iatStr = logDataTable.getValueAt(i, 8).toString(); if (timeStr.isEmpty() || loadStr.isEmpty() || rpmStr.isEmpty() || mafvStr.isEmpty() || afrStr.isEmpty() || stftStr.isEmpty() || ltftStr.isEmpty() || dvdtStr.isEmpty() || iatStr.isEmpty()) break; if (!Utils.validateDouble(timeStr, i, 0, tableName) || !Utils.validateDouble(loadStr, i, 1, tableName) || !Utils.validateDouble(rpmStr, i, 2, tableName) || !Utils.validateDouble(mafvStr, i, 3, tableName) || !Utils.validateDouble(afrStr, i, 4, tableName) || !Utils.validateDouble(stftStr, i, 5, tableName) || !Utils.validateDouble(ltftStr, i, 6, tableName) || !Utils.validateDouble(dvdtStr, i, 7, tableName) || !Utils.validateDouble(iatStr, i, 8, tableName)) return; time = Double.valueOf(timeStr); load = Double.valueOf(loadStr); rpm = Double.valueOf(rpmStr); mafv = Double.valueOf(mafvStr); afr = Double.valueOf(afrStr); stft = Double.valueOf(stftStr); ltft = Double.valueOf(ltftStr); dvdt = Double.valueOf(dvdtStr); iat = Double.valueOf(iatStr); corr = ltft + stft; trimArray.add(corr); rpmArray.add(rpm); timeArray.add(time); iatArray.add(iat); mafvArray.add(mafv); dvdtArray.add(dvdt); closestMafIdx = Utils.closestValueIndex(load * rpm / 60.0, gsArray); correctionMeanArray.set(closestMafIdx, (correctionMeanArray.get(closestMafIdx) * temp.get(closestMafIdx) + corr) / (temp.get(closestMafIdx) + 1)); temp.set(closestMafIdx, temp.get(closestMafIdx) + 1); modeCountMap = modeCalcArray.get(closestMafIdx); double roundedCorr = ((double) Math.round(corr * 10.0)) / 10.0; val = modeCountMap.get(roundedCorr); if (val == null) modeCountMap.put(roundedCorr, 1); else modeCountMap.put(roundedCorr, val + 1); closestRmpIdx = Utils.closestValueIndex(rpm, afrRpmArray) + 1; closestLoadIdx = Utils.closestValueIndex(load, afrLoadArray) + 1; val1 = (afr1Table.getValueAt(closestRmpIdx, closestLoadIdx).toString().isEmpty()) ? 0 : Double.valueOf(afr1Table.getValueAt(closestRmpIdx, closestLoadIdx).toString()); val2 = (afr2Table.getValueAt(closestRmpIdx, closestLoadIdx).toString().isEmpty()) ? 0 : Double.valueOf(afr2Table.getValueAt(closestRmpIdx, closestLoadIdx).toString()); afr1Table.setValueAt((val1 * val2 + afr) / (val2 + 1.0), closestRmpIdx, closestLoadIdx); afr2Table.setValueAt(val2 + 1.0, closestRmpIdx, closestLoadIdx); } for (i = 0; i < modeCalcArray.size(); ++i) { modeCountMap = modeCalcArray.get(i); if (modeCountMap.size() > 0) { int maxValueInMap = (Collections.max(modeCountMap.values())); double sum = 0; int count = 0; for (Entry<Double, Integer> entry : modeCountMap.entrySet()) { if (entry.getValue() == maxValueInMap) { sum += entry.getKey(); count += 1; } } correctionModeArray.set(i, sum / count); } } int size = afrRpmArray.size() + 1; while (size < afr1Table.getRowCount()) Utils.removeRow(size, afr1Table); while (size < afr2Table.getRowCount()) Utils.removeRow(size, afr2Table); Utils.colorTable(afr1Table); Utils.colorTable(afr2Table); int firstCorrIndex = 0; double firstCorr = 1; for (i = 0; i < correctionMeanArray.size(); ++i) { corr = 1; if (temp.get(i) > minCellHitCount) { corr = 1.0 + (correctionMeanArray.get(i) + correctionModeArray.get(i)) / 200.00; if (firstCorrIndex == 0) { firstCorrIndex = i; firstCorr = corr; } } gsCorrected.add(i, gsArray.get(i) * corr); } for (i = firstCorrIndex - 1; i > 0; --i) gsCorrected.set(i, gsArray.get(i) * firstCorr); } private boolean plotDvdtData() { return setXYSeries(runData, timeArray, dvdtArray); } private boolean plotIatData() { return setXYSeries(runData, timeArray, iatArray); } private boolean plotTrimRpmData() { if (setXYSeries(runData, rpmArray, trimArray)) { double[] ols = Regression .getOLSRegression(mafChartPanel.getChartPanel().getChart().getXYPlot().getDataset(1), 0); Function2D curve = new LineFunction2D(ols[0], ols[1]); currMafData.clear(); currMafData.add(runData.getMinX(), curve.getValue(runData.getMinX())); currMafData.add(runData.getMaxX(), curve.getValue(runData.getMaxX())); return true; } return false; } private boolean plotMeanModeData() { return (setXYSeries(runData, mafvArray, trimArray) && setXYSeries(currMafData, voltArray, correctionMeanArray) && setXYSeries(corrMafData, voltArray, correctionModeArray)); } private boolean plotCorrectionData() { ArrayList<Double> yarr = new ArrayList<Double>(); for (int i = 0; i < correctionMeanArray.size(); ++i) yarr.add((correctionMeanArray.get(i) + correctionModeArray.get(i)) / 2.0); return setXYSeries(runData, voltArray, yarr); } private void setRanges() { double paddingX; double paddingY; currMafData.setDescription(currentDataName); corrMafData.setDescription(correctedDataName); smoothMafData.setDescription(smoothedDataName); XYPlot plot = mafChartPanel.getChartPanel().getChart().getXYPlot(); plot.getDomainAxis(0).setLabel(XAxisName); plot.getRangeAxis(0).setLabel(Y1AxisName); plot.getRangeAxis(1).setLabel(Y2AxisName); plot.getRangeAxis(0).setVisible(true); plot.getRenderer(0).setSeriesVisible(0, true); plot.getRenderer(0).setSeriesVisible(1, true); plot.getRenderer(0).setSeriesVisible(2, true); if (checkBoxDvdtData.isSelected() && checkBoxDvdtData.isEnabled()) { paddingX = runData.getMaxX() * 0.05; paddingY = runData.getMaxY() * 0.05; plot.getDomainAxis(0).setRange(runData.getMinX() - paddingX, runData.getMaxX() + paddingX); plot.getRangeAxis(1).setRange(runData.getMinY() - paddingY, runData.getMaxY() + paddingY); plot.getRangeAxis(0).setVisible(false); plot.getRangeAxis(1).setLabel(dvdtAxisName); plot.getDomainAxis(0).setLabel(timeAxisName); plot.getRenderer(0).setSeriesVisible(0, false); plot.getRenderer(0).setSeriesVisible(1, false); plot.getRenderer(0).setSeriesVisible(2, false); } else if (checkBoxIatData.isSelected() && checkBoxIatData.isEnabled()) { paddingX = runData.getMaxX() * 0.05; paddingY = runData.getMaxY() * 0.05; plot.getDomainAxis(0).setRange(runData.getMinX() - paddingX, runData.getMaxX() + paddingX); plot.getRangeAxis(1).setRange(runData.getMinY() - paddingY, runData.getMaxY() + paddingY); plot.getRangeAxis(0).setVisible(false); plot.getRangeAxis(1).setLabel(iatAxisName); plot.getDomainAxis(0).setLabel(timeAxisName); plot.getRenderer(0).setSeriesVisible(0, false); plot.getRenderer(0).setSeriesVisible(1, false); plot.getRenderer(0).setSeriesVisible(2, false); } else if (checkBoxTrpmData.isSelected() && checkBoxTrpmData.isEnabled()) { paddingX = runData.getMaxX() * 0.05; paddingY = runData.getMaxY() * 0.05; plot.getDomainAxis(0).setRange(runData.getMinX() - paddingX, runData.getMaxX() + paddingX); plot.getRangeAxis(1).setRange(runData.getMinY() - paddingY, runData.getMaxY() + paddingY); plot.getRangeAxis(0).setRange(runData.getMinY() - paddingY, runData.getMaxY() + paddingY); plot.getRangeAxis(0).setVisible(false); plot.getRangeAxis(1).setLabel(trpmAxisName); plot.getDomainAxis(0).setLabel(rpmAxisName); plot.getRenderer(0).setSeriesVisible(0, false); plot.getRenderer(0).setSeriesVisible(1, false); currMafData.setDescription("Trend"); } else if (checkBoxMnmdData.isSelected() && checkBoxMnmdData.isEnabled()) { paddingX = runData.getMaxX() * 0.05; paddingY = runData.getMaxY() * 0.05; plot.getDomainAxis(0).setRange(runData.getMinX() - paddingX, runData.getMaxX() + paddingX); plot.getRangeAxis(1).setRange(runData.getMinY() - paddingY, runData.getMaxY() + paddingY); plot.getRangeAxis(0).setRange(runData.getMinY() - paddingY, runData.getMaxY() + paddingY); plot.getRangeAxis(0).setLabel(mnmdAxisName); plot.getRangeAxis(1).setLabel(mnmd2AxisName); plot.getDomainAxis(0).setLabel(XAxisName); plot.getRenderer(0).setSeriesVisible(0, false); currMafData.setDescription("Mean"); corrMafData.setDescription("Mode"); } else if (checkBoxRunData.isSelected() && checkBoxRunData.isEnabled() && !checkBoxCurrentMaf.isSelected() && !checkBoxCorrectedMaf.isSelected() && !checkBoxSmoothedMaf.isSelected()) { paddingX = runData.getMaxX() * 0.05; paddingY = runData.getMaxY() * 0.05; plot.getDomainAxis(0).setRange(runData.getMinX() - paddingX, runData.getMaxX() + paddingX); plot.getRangeAxis(1).setRange(runData.getMinY() - paddingY, runData.getMaxY() + paddingY); } else if (checkBoxSmoothing.isSelected()) { double maxY = Collections.max(Arrays.asList( new Double[] { currMafData.getMaxY(), smoothMafData.getMaxY(), corrMafData.getMaxY() })); double minY = Collections.max(Arrays.asList( new Double[] { currMafData.getMinY(), smoothMafData.getMinY(), corrMafData.getMinY() })); paddingX = smoothMafData.getMaxX() * 0.05; paddingY = maxY * 0.05; plot.getDomainAxis(0).setRange(smoothMafData.getMinX() - paddingX, smoothMafData.getMaxX() + paddingX); plot.getRangeAxis(0).setRange(minY - paddingY, maxY + paddingY); corrMafData.setDescription(mafCurveDataName); currMafData.setDescription(currentSlopeDataName); smoothMafData.setDescription(smoothedSlopeDataName); } else if ((checkBoxCurrentMaf.isSelected() && checkBoxCurrentMaf.isEnabled()) || (checkBoxCorrectedMaf.isSelected() && checkBoxCorrectedMaf.isEnabled()) || (checkBoxSmoothedMaf.isSelected() && checkBoxSmoothedMaf.isEnabled())) { paddingX = voltArray.get(voltArray.size() - 1) * 0.05; paddingY = gsCorrected.get(gsCorrected.size() - 1) * 0.05; plot.getDomainAxis(0).setRange(voltArray.get(0) - paddingX, voltArray.get(voltArray.size() - 1) + paddingX); plot.getRangeAxis(0).setRange(gsCorrected.get(0) - paddingY, gsCorrected.get(gsCorrected.size() - 1) + paddingY); if (checkBoxRunData.isSelected()) { paddingX = runData.getMaxX() * 0.05; paddingY = runData.getMaxY() * 0.05; plot.getRangeAxis(1).setRange(runData.getMinY() - paddingY, runData.getMaxY() + paddingY); } } else { plot.getRangeAxis(0).setAutoRange(true); plot.getDomainAxis(0).setAutoRange(true); } } protected void onEnableSmoothingView(boolean flag) { checkBoxDvdtData.setEnabled(!flag); checkBoxIatData.setEnabled(!flag); checkBoxTrpmData.setEnabled(!flag); checkBoxMnmdData.setEnabled(!flag); if (flag == false) { if (checkBoxDvdtData.isSelected()) plotDvdtData(); else if (checkBoxIatData.isSelected()) plotIatData(); else if (checkBoxTrpmData.isSelected()) plotTrimRpmData(); else if (checkBoxMnmdData.isSelected()) plotMeanModeData(); else { if (checkBoxRunData.isSelected()) plotCorrectionData(); if (checkBoxCurrentMaf.isSelected()) plotCurrentMafData(); if (checkBoxCorrectedMaf.isSelected()) setCorrectedMafData(); if (checkBoxSmoothedMaf.isSelected()) setSmoothedMafData(); } } } protected void onSmoothReset() { if (!checkBoxDvdtData.isEnabled() || !checkBoxDvdtData.isSelected() || !checkBoxTrpmData.isEnabled() || !checkBoxTrpmData.isSelected() || !checkBoxMnmdData.isEnabled() || !checkBoxMnmdData.isSelected() || !checkBoxIatData.isEnabled() || !checkBoxIatData.isSelected()) setCorrectedMafData(); if (checkBoxSmoothing.isSelected()) plotSmoothingLineSlopes(); else if (checkBoxSmoothedMaf.isSelected()) setSmoothedMafData(); } public void saveData() { if (JFileChooser.APPROVE_OPTION != fileChooser.showSaveDialog(this)) return; File file = fileChooser.getSelectedFile(); setCursor(new Cursor(Cursor.WAIT_CURSOR)); int i, j; FileWriter out = null; try { out = new FileWriter(file); // write string identifier out.write(SaveDataFileHeader + "\n"); // write maf data for (i = 0; i < mafTable.getRowCount(); ++i) { for (j = 0; j < mafTable.getColumnCount(); ++j) out.write(mafTable.getValueAt(i, j).toString() + ","); out.write("\n"); } // write log data for (i = 0; i < logDataTable.getRowCount(); ++i) { for (j = 0; j < logDataTable.getColumnCount(); ++j) out.write(logDataTable.getValueAt(i, j).toString() + ","); out.write("\n"); } } catch (Exception e) { e.printStackTrace(); logger.error(e); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); if (out != null) { try { out.close(); } catch (IOException e) { logger.error(e); } } } } public void loadData() { fileChooser.setMultiSelectionEnabled(false); if (JFileChooser.APPROVE_OPTION != fileChooser.showOpenDialog(this)) return; File file = fileChooser.getSelectedFile(); int i, j; setCursor(new Cursor(Cursor.WAIT_CURSOR)); BufferedReader br = null; try { br = new BufferedReader(new FileReader(file.getAbsoluteFile())); String line = br.readLine(); if (line == null || !line.equals(SaveDataFileHeader)) { JOptionPane.showMessageDialog(null, "Invalid saved data file!", "Error", JOptionPane.ERROR_MESSAGE); return; } line = br.readLine(); String[] elements; i = 0; int offset = 0; boolean isLogData = false; while (line != null) { elements = line.split(",", -1); switch (i) { case 0: Utils.ensureColumnCount(elements.length - 1, mafTable); for (j = 0; j < elements.length - 1; ++j) mafTable.setValueAt(elements[j], i, j); break; case 1: Utils.ensureColumnCount(elements.length - 1, mafTable); for (j = 0; j < elements.length - 1; ++j) mafTable.setValueAt(elements[j], i, j); break; default: if (elements.length - 1 == logDataTable.getColumnCount()) { if (!isLogData) { offset = i; isLogData = true; } Utils.ensureRowCount(i - offset + 1, logDataTable); for (j = 0; j < elements.length - 1; ++j) logDataTable.setValueAt(elements[j], i - offset, j); } } i += 1; line = br.readLine(); } } catch (Exception e) { e.printStackTrace(); logger.error(e); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); if (br != null) { try { br.close(); } catch (IOException e) { logger.error(e); } } } } private int getLogTableEmptyRow() { if (logDataTable.getValueAt(0, 0) != null && logDataTable.getValueAt(0, 0).toString().isEmpty()) return 0; if (logDataTable.getValueAt(logDataTable.getRowCount() - 1, 0) != null && !logDataTable.getValueAt(0, 0).toString().isEmpty()) return logDataTable.getRowCount(); for (int i = logDataTable.getRowCount() - 2; i > 0; --i) { if (logDataTable.getValueAt(i, 0) != null && !logDataTable.getValueAt(i, 0).toString().isEmpty()) return i + 1; } return 0; } private boolean getColumnsFilters(String[] elements) { boolean ret = true; ArrayList<String> columns = new ArrayList<String>(Arrays.asList(elements)); String logClOlStatusColName = Config.getClOlStatusColumnName(); String logAfLearningColName = Config.getAfLearningColumnName(); String logAfCorrectionColName = Config.getAfCorrectionColumnName(); String logAfrColName = Config.getAfrColumnName(); String logRpmColName = Config.getRpmColumnName(); String logLoadColName = Config.getLoadColumnName(); String logTimeColName = Config.getTimeColumnName(); String logMafvColName = Config.getMafVoltageColumnName(); String logIatColName = Config.getIatColumnName(); logClOlStatusColIdx = columns.indexOf(logClOlStatusColName); logAfLearningColIdx = columns.indexOf(logAfLearningColName); logAfCorrectionColIdx = columns.indexOf(logAfCorrectionColName); logAfrColIdx = columns.indexOf(logAfrColName); logRpmColIdx = columns.indexOf(logRpmColName); logLoadColIdx = columns.indexOf(logLoadColName); logTimeColIdx = columns.indexOf(logTimeColName); logMafvColIdx = columns.indexOf(logMafvColName); logIatColIdx = columns.indexOf(logIatColName); if (logClOlStatusColIdx == -1) { Config.setClOlStatusColumnName(Config.NO_NAME); ret = false; } if (logAfLearningColIdx == -1) { Config.setAfLearningColumnName(Config.NO_NAME); ret = false; } if (logAfCorrectionColIdx == -1) { Config.setAfCorrectionColumnName(Config.NO_NAME); ret = false; } if (logAfrColIdx == -1) { Config.setAfrColumnName(Config.NO_NAME); ret = false; } if (logRpmColIdx == -1) { Config.setRpmColumnName(Config.NO_NAME); ret = false; } if (logLoadColIdx == -1) { Config.setLoadColumnName(Config.NO_NAME); ret = false; } if (logTimeColIdx == -1) { Config.setTimeColumnName(Config.NO_NAME); ret = false; } if (logMafvColIdx == -1) { Config.setMafVoltageColumnName(Config.NO_NAME); ret = false; } if (logIatColIdx == -1) { Config.setIatColumnName(Config.NO_NAME); ret = false; } clValue = Config.getClOlStatusValue(); minCellHitCount = Config.getCLMinCellHitCount(); afrMin = Config.getAfrMinimumValue(); afrMax = Config.getAfrMaximumValue(); minLoad = Config.getLoadMinimumValue(); maxDvDt = Config.getDvDtMaximumValue(); maxMafV = Config.getMafVMaximumValue(); maxIat = Config.getIatMaximumValue(); return ret; } protected void loadLogFile() { fileChooser.setMultiSelectionEnabled(true); if (JFileChooser.APPROVE_OPTION != fileChooser.showOpenDialog(this)) return; boolean isPolSet = polfTable.isSet(); File[] files = fileChooser.getSelectedFiles(); for (File file : files) { BufferedReader br = null; try { br = new BufferedReader(new FileReader(file.getAbsoluteFile())); String line = br.readLine(); if (line != null) { String[] elements = line.split("(\\s*)?,(\\s*)?", -1); getColumnsFilters(elements); boolean resetColumns = false; if (logClOlStatusColIdx >= 0 || logAfLearningColIdx >= 0 || logAfCorrectionColIdx >= 0 || logAfrColIdx >= 0 || logRpmColIdx >= 0 || logLoadColIdx >= 0 || logTimeColIdx >= 0 || logMafvColIdx >= 0 || logIatColIdx >= 0) { if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(null, "Would you like to reset column names or filter values?", "Columns/Filters Reset", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE)) resetColumns = true; } if (resetColumns || logClOlStatusColIdx < 0 || logAfLearningColIdx < 0 || logAfCorrectionColIdx < 0 || logAfrColIdx < 0 || logRpmColIdx < 0 || logLoadColIdx < 0 || logTimeColIdx < 0 || logMafvColIdx < 0 || logIatColIdx < 0) { ColumnsFiltersSelection selectionWindow = new CLColumnsFiltersSelection(isPolSet); if (!selectionWindow.getUserSettings(elements) || !getColumnsFilters(elements)) return; } String[] flds; line = br.readLine(); int clol; int i = 2; int row = getLogTableEmptyRow(); double afr = 0; double dVdt = 0; double prevTime = 0; double time = 0; double timeMultiplier = 1.0; double pmafv = 0; double mafv = 0; double load; double iat; setCursor(new Cursor(Cursor.WAIT_CURSOR)); while (line != null) { flds = line.split(",", -1); try { // Calculate dV/dt prevTime = time; time = Double.valueOf(flds[logTimeColIdx]); if (timeMultiplier == 1.0 && (int) time - time < 0) { timeMultiplier = 1000.0; prevTime *= timeMultiplier; } time *= timeMultiplier; pmafv = mafv; mafv = Double.valueOf(flds[logMafvColIdx]); if ((time - prevTime) == 0.0) dVdt = 100.0; else dVdt = Math.abs(((mafv - pmafv) / (time - prevTime)) * 1000.0); clol = Integer.valueOf(flds[logClOlStatusColIdx]); if (clol == clValue) { // Filters afr = Double.valueOf(flds[logAfrColIdx]); load = Double.valueOf(flds[logLoadColIdx]); iat = Double.valueOf(flds[logIatColIdx]); if (afrMin <= afr && afr <= afrMax && minLoad <= load && dVdt <= maxDvDt && maxMafV >= mafv && maxIat >= iat) { Utils.ensureRowCount(row + 1, logDataTable); logDataTable.setValueAt(time, row, 0); logDataTable.setValueAt(load, row, 1); logDataTable.setValueAt(Double.valueOf(flds[logRpmColIdx]), row, 2); logDataTable.setValueAt(mafv, row, 3); logDataTable.setValueAt(afr, row, 4); logDataTable.setValueAt(Double.valueOf(flds[logAfCorrectionColIdx]), row, 5); logDataTable.setValueAt(Double.valueOf(flds[logAfLearningColIdx]), row, 6); logDataTable.setValueAt(dVdt, row, 7); logDataTable.setValueAt(iat, row, 8); row += 1; } } } catch (NumberFormatException e) { logger.error(e); JOptionPane.showMessageDialog(null, "Error parsing number at " + file.getName() + " line " + i + ": " + e, "Error processing file", JOptionPane.ERROR_MESSAGE); return; } line = br.readLine(); i += 1; } } } catch (Exception e) { logger.error(e); JOptionPane.showMessageDialog(null, e, "Error opening file", JOptionPane.ERROR_MESSAGE); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); if (br != null) { try { br.close(); } catch (IOException e) { logger.error(e); } } } } } protected String usage() { ResourceBundle bundle; bundle = ResourceBundle.getBundle("com.vgi.mafscaling.closed_loop"); return bundle.getString("usage"); } }