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.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.ResourceBundle; import java.util.TreeMap; 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.border.LineBorder; import javax.swing.table.DefaultTableModel; import org.apache.log4j.Logger; import org.jfree.chart.plot.XYPlot; import org.jfree.data.xy.XYSeries; public class OpenLoop extends AMafScaling { private static final long serialVersionUID = 2988105467764335997L; private static final Logger logger = Logger.getLogger(OpenLoop.class); private static final String SaveDataFileHeader = "[open_loop run data]"; private static final String RunTableName = "Run "; private static final String Y2AxisName = "AFR Error (%)"; private static final String rpmAxisName = "RPM"; private static final String runDataName = "AFR Error"; private static final int RunCount = 12; private static final int RunRowsCount = 200; private double minMafV = Config.getMafVMinimumValue(); private double afrErrPrct = Config.getWidebandAfrErrorPercentValue(); private double minWotEnrichment = Config.getWOTEnrichmentValue(); private int wotPoint = Config.getWOTStationaryPointValue(); private int afrRowOffset = Config.getWBO2RowOffset(); private int skipRowsOnTransition = Config.getOLCLTransitionSkipRows(); private int logThtlAngleColIdx = -1; private int logAfLearningColIdx = -1; private int logAfCorrectionColIdx = -1; private int logMafvColIdx = -1; private int logAfrColIdx = -1; private int logRpmColIdx = -1; private int logLoadColIdx = -1; private int logCommandedAfrCol = -1; private JCheckBox checkBoxMafRpmData = null; private ArrayList<Double> afrArray = new ArrayList<Double>(); private final JTable[] runTables = new JTable[RunCount]; public OpenLoop(int tabPlacement, PrimaryOpenLoopFuelingTable table, MafCompare comparer) { super(tabPlacement, table, comparer); runData = new XYSeries(runDataName); initialize(); } ////////////////////////////////////////////////////////////////////////////////////// // DATA TAB ////////////////////////////////////////////////////////////////////////////////////// protected void createRunPanel(JPanel dataPanel) { JScrollPane dataScrollPane = new JScrollPane(); GridBagConstraints gbc_dataScrollPane = new GridBagConstraints(); gbc_dataScrollPane.weightx = 1.0; gbc_dataScrollPane.weighty = 1.0; gbc_dataScrollPane.fill = GridBagConstraints.BOTH; gbc_dataScrollPane.gridx = 0; gbc_dataScrollPane.gridy = 3; dataPanel.add(dataScrollPane, gbc_dataScrollPane); JPanel dataRunPanel = new JPanel(); dataScrollPane.setViewportView(dataRunPanel); GridBagLayout gbl_dataRunPanel = new GridBagLayout(); gbl_dataRunPanel.columnWidths = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; gbl_dataRunPanel.rowHeights = new int[] { 0 }; gbl_dataRunPanel.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, 1.0 }; gbl_dataRunPanel.rowWeights = new double[] { 0.0 }; dataRunPanel.setLayout(gbl_dataRunPanel); createRunTables(dataRunPanel); } private void createRunTables(JPanel dataRunPanel) { GridBagConstraints gbc_run = new GridBagConstraints(); gbc_run.anchor = GridBagConstraints.PAGE_START; gbc_run.insets = new Insets(0, 2, 0, 2); for (int i = 0; i < RunCount; ++i) { runTables[i] = new JTable(); JTable table = runTables[i]; table.getTableHeader().setReorderingAllowed(false); table.setModel(new DefaultTableModel(RunRowsCount, 3)); table.setColumnSelectionAllowed(true); table.setCellSelectionEnabled(true); table.setBorder(new LineBorder(new Color(0, 0, 0))); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); table.getColumnModel().getColumn(0) .setHeaderValue("<html><center>Engine<br>Speed<br>(RPM)<br></center></html>"); table.getColumnModel().getColumn(1) .setHeaderValue("<html><center>MAF<br>Sensor<br>Voltage<br></center></html>"); table.getColumnModel().getColumn(2) .setHeaderValue("<html><center>AFR<br>Error<br>%<br></center></html>"); Utils.initializeTable(table, ColumnWidth); excelAdapter.addTable(table, true, false); gbc_run.gridx = i; gbc_run.gridy = 0; dataRunPanel.add(table.getTableHeader(), gbc_run); gbc_run.gridy = 1; dataRunPanel.add(table, gbc_run); } } ////////////////////////////////////////////////////////////////////////////////////// // 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 }; 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, 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; checkBoxMafRpmData = new JCheckBox("MafV/RPM"); checkBoxMafRpmData.setActionCommand("mafrpm"); checkBoxMafRpmData.addActionListener(this); cntlPanel.add(checkBoxMafRpmData, gbc_check); gbc_check.gridx++; checkBoxRunData = new JCheckBox("AFR Error"); checkBoxRunData.setActionCommand("rdata"); checkBoxRunData.addActionListener(this); cntlPanel.add(checkBoxRunData, gbc_check); gbc_check.gridx++; createGraphCommonControls(cntlPanel, gbc_check.gridx); createChart(plotPanel, Y2AxisName); createMafSmoothingPanel(plotPanel); } ////////////////////////////////////////////////////////////////////////////////////// // COMMON ACTIONS RELATED FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////// @Override public void actionPerformed(ActionEvent e) { if (checkActionPerformed(e)) return; if ("mafrpm".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { clearNotRunDataCheckboxes(); if (!plotMafVRpmData()) checkBox.setSelected(false); } else runData.clear(); setRanges(); } else if ("rdata".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { if (checkBoxMafRpmData.isSelected()) { checkBoxMafRpmData.setSelected(false); runData.clear(); } if (!plotRunData()) checkBox.setSelected(false); } else runData.clear(); setRanges(); } else if ("current".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { if (checkBoxMafRpmData.isSelected()) { checkBoxMafRpmData.setSelected(false); runData.clear(); } if (!plotCurrentMafData()) checkBox.setSelected(false); } else currMafData.clear(); setRanges(); } else if ("corrected".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { if (checkBoxMafRpmData.isSelected()) { checkBoxMafRpmData.setSelected(false); runData.clear(); } if (!setCorrectedMafData()) checkBox.setSelected(false); } else corrMafData.clear(); setRanges(); } else if ("smoothed".equals(e.getActionCommand())) { JCheckBox checkBox = (JCheckBox) e.getSource(); if (checkBox.isSelected()) { if (checkBoxMafRpmData.isSelected()) { checkBoxMafRpmData.setSelected(false); runData.clear(); } 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(); } } protected void clearRunTables() { setCursor(new Cursor(Cursor.WAIT_CURSOR)); try { for (int i = 0; i < runTables.length; ++i) { while (RunRowsCount < runTables[i].getRowCount()) Utils.removeRow(RunRowsCount, runTables[i]); Utils.clearTable(runTables[i]); } } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } } protected void clearData() { super.clearData(); afrArray.clear(); } protected void clearChartCheckBoxes() { super.clearChartCheckBoxes(); checkBoxMafRpmData.setSelected(false); } protected void calculateMafScaling() { setCursor(new Cursor(Cursor.WAIT_CURSOR)); try { clearData(); clearChartData(); clearChartCheckBoxes(); TreeMap<Integer, ArrayList<Double>> result = new TreeMap<Integer, ArrayList<Double>>(); if (!getMafTableData(voltArray, gsArray)) return; if (!sortRunData(result) || result.isEmpty()) return; calculateCorrectedGS(result); setCorrectedMafData(); smoothGsArray.addAll(gsCorrected); checkBoxCorrectedMaf.setSelected(true); setXYTable(mafSmoothingTable, voltArray, smoothGsArray); setRanges(); setSelectedIndex(1); } 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 boolean sortRunData(TreeMap<Integer, ArrayList<Double>> result) { int closestVoltIdx; double rpm; double voltage; double error; ArrayList<Double> closestVolatageArray; for (int i = 0; i < runTables.length; ++i) { JTable table = runTables[i]; String tableName = RunTableName + (i + 1); String rpmValue; String mafvValue; String afrValue; for (int j = 0; j < table.getRowCount(); ++j) { rpmValue = table.getValueAt(j, 0).toString(); mafvValue = table.getValueAt(j, 1).toString(); afrValue = table.getValueAt(j, 2).toString(); if (rpmValue.isEmpty() || mafvValue.isEmpty() || afrValue.isEmpty()) continue; if (!Utils.validateDouble(rpmValue, j, 0, tableName) || !Utils.validateDouble(mafvValue, j, 1, tableName) || !Utils.validateDouble(afrValue, j, 2, tableName)) return false; rpm = Double.parseDouble(rpmValue); voltage = Double.parseDouble(mafvValue); error = Double.parseDouble(afrValue); rpmArray.add(rpm); mafvArray.add(voltage); afrArray.add(error); closestVoltIdx = Utils.closestValueIndex(voltage, voltArray); closestVolatageArray = result.get(closestVoltIdx); if (closestVolatageArray == null) { closestVolatageArray = new ArrayList<Double>(); result.put(closestVoltIdx, closestVolatageArray); } closestVolatageArray.add(error); } } return true; } private void calculateCorrectedGS(TreeMap<Integer, ArrayList<Double>> result) { ArrayList<Double> closestVolatageArray; double gs = 0; double avgError = 0; int lastErrIndex = 0; int i; gsCorrected.addAll(gsArray); for (i = 0; i < gsCorrected.size(); ++i) { gs = gsCorrected.get(i); avgError = 0; closestVolatageArray = result.get(i); if (closestVolatageArray != null) { for (int j = 0; j < closestVolatageArray.size(); ++j) avgError += closestVolatageArray.get(j); avgError /= closestVolatageArray.size(); lastErrIndex = i; } gsCorrected.set(i, gs * (1 + avgError / 100.0)); } avgError = 0; ArrayList<Double> sortedAfrArray = result.get(lastErrIndex); Collections.sort(sortedAfrArray, Collections.reverseOrder()); for (i = 0; i < 10 && i < sortedAfrArray.size(); ++i) avgError += sortedAfrArray.get(i); if (i > 0) avgError /= i; for (i = lastErrIndex + 1; i < gsCorrected.size(); ++i) { gs = gsCorrected.get(i); gsCorrected.set(i, gs + (gs * 0.01 * avgError)); } } private boolean plotMafVRpmData() { return setXYSeries(runData, rpmArray, mafvArray); } private boolean plotRunData() { return setXYSeries(runData, mafvArray, afrArray); } private void setRanges() { double paddingX; double paddingY; XYPlot plot = mafChartPanel.getChartPanel().getChart().getXYPlot(); plot.getDomainAxis(0).setLabel(XAxisName); plot.getRangeAxis(1).setLabel(Y2AxisName); plot.getRangeAxis(0).setVisible(true); if (checkBoxMafRpmData.isSelected() && checkBoxMafRpmData.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(XAxisName); plot.getDomainAxis(0).setLabel(rpmAxisName); } 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.min(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); } 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) { checkBoxMafRpmData.setEnabled(!flag); if (flag == false) { if (checkBoxMafRpmData.isSelected()) plotMafVRpmData(); if (checkBoxRunData.isSelected()) plotRunData(); if (checkBoxCurrentMaf.isSelected()) plotCurrentMafData(); if (checkBoxCorrectedMaf.isSelected()) setCorrectedMafData(); if (checkBoxSmoothedMaf.isSelected()) setSmoothedMafData(); } } protected void onSmoothReset() { if (!checkBoxMafRpmData.isEnabled() || !checkBoxMafRpmData.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 run data for (int t = 0; t < runTables.length; ++t) { for (i = 0; i < runTables[t].getColumnCount(); ++i) { for (j = 0; j < runTables[t].getRowCount(); ++j) out.write(runTables[t].getValueAt(j, i).toString() + ","); out.write("\n"); } } } catch (Exception e) { 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, k, l; 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; JTable table = null; i = k = l = 0; 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: int offset = runTables.length * 3 + mafTable.getRowCount(); if (i > 1 && i < offset) { if (l == 0) table = runTables[k++]; Utils.ensureRowCount(elements.length - 1, table); for (j = 0; j < elements.length - 1; ++j) table.setValueAt(elements[j], j, l); l += 1; if (l == 3) l = 0; } } 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 boolean getColumnsFilters(String[] elements, boolean isPolSet) { boolean ret = true; ArrayList<String> columns = new ArrayList<String>(Arrays.asList(elements)); String logThtlAngleColName = Config.getThrottleAngleColumnName(); String logAfLearningColName = Config.getAfLearningColumnName(); String logAfCorrectionColName = Config.getAfCorrectionColumnName(); String logMafvColName = Config.getMafVoltageColumnName(); String logAfrColName = Config.getWidebandAfrColumnName(); String logRpmColName = Config.getRpmColumnName(); String logLoadColName = Config.getLoadColumnName(); String logCommandedAfrColName = Config.getCommandedAfrColumnName(); logThtlAngleColIdx = columns.indexOf(logThtlAngleColName); logAfLearningColIdx = columns.indexOf(logAfLearningColName); logAfCorrectionColIdx = columns.indexOf(logAfCorrectionColName); logMafvColIdx = columns.indexOf(logMafvColName); logAfrColIdx = columns.indexOf(logAfrColName); logRpmColIdx = columns.indexOf(logRpmColName); logLoadColIdx = columns.indexOf(logLoadColName); logCommandedAfrCol = columns.indexOf(logCommandedAfrColName); if (logThtlAngleColIdx == -1) { Config.setThrottleAngleColumnName(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 (logMafvColIdx == -1) { Config.setMafVoltageColumnName(Config.NO_NAME); ret = false; } if (logAfrColIdx == -1) { Config.setWidebandAfrColumnName(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 (logCommandedAfrCol == -1) { Config.setCommandedAfrColumnName(Config.NO_NAME); if (!isPolSet) ret = false; } wotPoint = Config.getWOTStationaryPointValue(); minMafV = Config.getMafVMinimumValue(); afrErrPrct = Config.getWidebandAfrErrorPercentValue(); minWotEnrichment = Config.getWOTEnrichmentValue(); afrRowOffset = Config.getWBO2RowOffset(); skipRowsOnTransition = Config.getOLCLTransitionSkipRows(); 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; ArrayDeque<String[]> buffer = new ArrayDeque<String[]>(); try { br = new BufferedReader(new FileReader(file.getAbsoluteFile())); String line = br.readLine(); if (line != null) { String[] elements = line.split("(\\s*)?,(\\s*)?", -1); getColumnsFilters(elements, false); boolean resetColumns = false; if (logThtlAngleColIdx >= 0 || logAfLearningColIdx >= 0 || logAfCorrectionColIdx >= 0 || logMafvColIdx >= 0 || logAfrColIdx >= 0 || logRpmColIdx >= 0 || logLoadColIdx >= 0 || logCommandedAfrCol >= 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 || logThtlAngleColIdx < 0 || logAfLearningColIdx < 0 || logAfCorrectionColIdx < 0 || logMafvColIdx < 0 || logAfrColIdx < 0 || logRpmColIdx < 0 || logLoadColIdx < 0 || (logCommandedAfrCol < 0 && !isPolSet)) { ColumnsFiltersSelection selectionWindow = new OLColumnsFiltersSelection(isPolSet); if (!selectionWindow.getUserSettings(elements) || !getColumnsFilters(elements, isPolSet)) return; } String[] flds; String[] afrflds; boolean wotFlag = true; boolean foundWot = false; double throttle; double stft; double ltft; double afr; double rpm; double load; double mafv; double cmdafr = 0; double afrErr = 0; int skipRowCount = 0; int row = 0; int i = 0; int j = 0; for (; i < runTables.length; ++i) { if (runTables[i].getValueAt(0, 0).toString().isEmpty()) break; } if (i == runTables.length) return; setCursor(new Cursor(Cursor.WAIT_CURSOR)); for (int k = 0; k <= afrRowOffset && line != null; ++k) { line = br.readLine(); if (line != null) buffer.addFirst(line.split(",", -1)); } while (line != null && buffer.size() > afrRowOffset) { afrflds = buffer.getFirst(); flds = buffer.removeLast(); line = br.readLine(); if (line != null) buffer.addFirst(line.split(",", -1)); try { throttle = Double.valueOf(flds[logThtlAngleColIdx]); if (row == 0 && throttle < 99) wotFlag = false; if (throttle < wotPoint) { if (wotFlag == true) { wotFlag = false; skipRowCount = 0; j -= 1; while (j > 0 && skipRowCount < skipRowsOnTransition) { runTables[i].setValueAt("", j, 0); runTables[i].setValueAt("", j, 1); runTables[i].setValueAt("", j, 2); skipRowCount += 1; j -= 1; } skipRowCount = 0; } } else { if (wotFlag == false) { wotFlag = true; skipRowCount = 0; if (foundWot) { i += 1; if (i == runTables.length) return; } if (row > 0) j = 0; } if (skipRowCount >= skipRowsOnTransition) { mafv = Double.valueOf(flds[logMafvColIdx]); if (minMafV <= mafv) { foundWot = true; stft = Double.valueOf(flds[logAfCorrectionColIdx]); ltft = Double.valueOf(flds[logAfLearningColIdx]); afr = Double.valueOf(afrflds[logAfrColIdx]); rpm = Double.valueOf(flds[logRpmColIdx]); load = Double.valueOf(flds[logLoadColIdx]); afr = afr / ((100.0 - (ltft + stft)) / 100.0); if (logCommandedAfrCol >= 0) cmdafr = Double.valueOf(flds[logCommandedAfrCol]); else if (isPolSet) cmdafr = Utils.calculateCommandedAfr(rpm, load, minWotEnrichment, polfTable); else { JOptionPane.showMessageDialog(null, "Please set either \"Commanded AFR\" column or \"Primary Open Loop Fueling\" table", "Error", JOptionPane.ERROR_MESSAGE); return; } afrErr = (afr - cmdafr) / cmdafr * 100.0; if (Math.abs(afrErr) <= afrErrPrct) { Utils.ensureRowCount(j + 1, runTables[i]); runTables[i].setValueAt(rpm, j, 0); runTables[i].setValueAt(mafv, j, 1); runTables[i].setValueAt(afrErr, j, 2); j += 1; } } } skipRowCount += 1; } } catch (NumberFormatException e) { logger.error(e); JOptionPane.showMessageDialog(null, "Error parsing number at " + file.getName() + " line " + (row + 1) + ": " + e, "Error processing file", JOptionPane.ERROR_MESSAGE); return; } row += 1; } if (!foundWot) { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); JOptionPane.showMessageDialog(null, "Sorry, no WOT pulls were found in the log file", "No WOT data", JOptionPane.INFORMATION_MESSAGE); } } } 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.open_loop"); return bundle.getString("usage"); } }