mirror of https://github.com/rusefi/rusefi.git
202 lines
7.6 KiB
Java
202 lines
7.6 KiB
Java
package com.rusefi.tools.tune;
|
|
|
|
import com.opensr5.ini.IniFileModel;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.io.*;
|
|
import java.util.Date;
|
|
import java.util.function.Function;
|
|
|
|
/**
|
|
* tuner studio project to C data structure converter command line utility
|
|
* <p>
|
|
* 12/27/2014
|
|
* Andrey Belomutskiy, (c) 2012-2016
|
|
*/
|
|
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
|
|
public class TS2C {
|
|
public static final Function<String, Reader> fileFactory = new Function<String, Reader>() {
|
|
@Override
|
|
public Reader apply(String fileName) {
|
|
try {
|
|
return new FileReader(fileName);
|
|
} catch (FileNotFoundException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
public static String FINGER_PRINT = "/* Generated by " + TS2C.class.getSimpleName() + " on " + new Date() + "*/\n";
|
|
|
|
/**
|
|
* @see TS2CRunner
|
|
*/
|
|
/*
|
|
public static void main(String[] args) throws IOException {
|
|
new TS2C(args);
|
|
}
|
|
*/
|
|
private TS2C(String[] args) throws IOException {
|
|
System.out.println("This tool reads TS tune file and produces some C code for hardcoded base tunes");
|
|
if (args.length != 3 && args.length != 4 && args.length != 5) {
|
|
System.out.println("Three parameters expected: ");
|
|
System.out.println(" INPUT_MSQ_FILE NAME LOAD_SECTION_NAME RPM_SECTION_NAME [TABLE_NAME]");
|
|
System.out.println("for example");
|
|
// section names are needed in order to generate comments about cell content
|
|
System.out.println(" currenttune.msq veLoadBins veRpmBins veTable");
|
|
System.exit(-1);
|
|
}
|
|
String msqFileName = args[0];
|
|
String loadSectionName = args[1];
|
|
String rpmSectionName = args[2];
|
|
String tableName = args.length == 3 ? "none" : args[3];
|
|
|
|
IniFileModel model = IniFileModel.getInstance();
|
|
|
|
String entityName = tableName.equalsIgnoreCase("none") ? loadSectionName : tableName;
|
|
String methodName = getMethodName(entityName);
|
|
|
|
BufferedWriter w = new BufferedWriter(new FileWriter("generated_" + methodName + ".cpp"));
|
|
|
|
|
|
CurveData loadBins = null;
|
|
CurveData rpmBins = null;
|
|
|
|
if (!loadSectionName.equalsIgnoreCase("none")) {
|
|
loadBins = CurveData.processCurve(msqFileName, loadSectionName, model, w);
|
|
}
|
|
|
|
if (!rpmSectionName.equalsIgnoreCase("none")) {
|
|
rpmBins = CurveData.processCurve(msqFileName, rpmSectionName, model, w);
|
|
}
|
|
|
|
if (!tableName.equalsIgnoreCase("none")) {
|
|
String sb = getTableCSourceCode2(msqFileName, tableName, model, rpmBins, loadBins);
|
|
|
|
w.write(sb);
|
|
|
|
}
|
|
|
|
w.write(FINGER_PRINT);
|
|
w.write("static void set" + methodName + "() {\n");
|
|
w.write("\tMEMCPY(config->" + loadSectionName + ", hardCoded" + loadSectionName + ");\n");
|
|
w.write("\tMEMCPY(config->" + rpmSectionName + ", hardCoded" + rpmSectionName + ");\n");
|
|
|
|
if (!tableName.equalsIgnoreCase("none")) {
|
|
w.write("\tMEMCPY(config->" + tableName + ", hardCoded" + tableName + ");\n");
|
|
}
|
|
|
|
|
|
w.write("}\n");
|
|
|
|
w.close();
|
|
}
|
|
|
|
public static String getTableCSourceCode2(String msqFileName, String tableName, IniFileModel model) throws IOException {
|
|
String xRpmBinsName = model.getXBin(tableName);
|
|
String yLoadBinsName = model.getYBin(tableName);
|
|
|
|
CurveData xRpmCurve = CurveData.valueOf(msqFileName, xRpmBinsName, model);
|
|
CurveData yLoadCurve = CurveData.valueOf(msqFileName, yLoadBinsName, model);
|
|
return getTableCSourceCode2(msqFileName, tableName, model, xRpmCurve, yLoadCurve);
|
|
}
|
|
|
|
@NotNull
|
|
public static String getTableCSourceCode2(String msqFileName, String tableName, IniFileModel model, CurveData xRpmCurve, CurveData yLoadBins) throws IOException {
|
|
TableData table = TableData.readTable(msqFileName, tableName, model);
|
|
|
|
return getTableCSourceCode(tableName, yLoadBins, xRpmCurve, table.floats);
|
|
}
|
|
|
|
private static String getTableCSourceCode(String tableName, CurveData loadBins, CurveData rpmBins, float[][] table) {
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append("static const float hardCoded" + tableName + "[" + table.length + "][" + table[0].length + "] = {\n");
|
|
|
|
writeTable(loadBins, rpmBins, sb, (loadIndex, rpmIndex) -> table[loadIndex][rpmIndex]);
|
|
sb.append("};\n\n");
|
|
return sb.toString();
|
|
}
|
|
|
|
@NotNull
|
|
private static String getMethodName(String methodName) {
|
|
return methodName.toUpperCase().charAt(0) + methodName.substring(1);
|
|
}
|
|
|
|
private static void writeTable(CurveData loadBins, CurveData rpmBins, StringBuilder sb, ValueSource valueSource) {
|
|
sb.append(FINGER_PRINT);
|
|
for (int loadIndex = 0; loadIndex < loadBins.getRawData().length; loadIndex++) {
|
|
String line = writeTableLine(loadBins, rpmBins, valueSource, loadIndex);
|
|
sb.append(line);
|
|
}
|
|
}
|
|
|
|
public static void writePlainTable(int rows, int columns, StringBuilder sb, ValueSource valueSource) {
|
|
for (int row = 0; row < rows; row++) {
|
|
String line = writePlainTableLine(valueSource, row, columns);
|
|
sb.append(line);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param fileName text file to open
|
|
* @param magicStringKey magic string content to scroll to
|
|
* @param factory
|
|
* @return Reader after the magicStringKey line
|
|
*/
|
|
static BufferedReader readAndScroll(String fileName, String magicStringKey, Function<String, Reader> factory) throws IOException {
|
|
|
|
Reader reader = factory.apply(fileName);
|
|
BufferedReader br = new BufferedReader(reader);
|
|
System.out.println("Reading from " + new File(fileName).getAbsolutePath() + ", scrolling to " + magicStringKey);
|
|
String line;
|
|
while ((line = br.readLine()) != null) {
|
|
if (line.contains(magicStringKey)) {
|
|
// System.out.println("Found " + line);
|
|
break;
|
|
}
|
|
}
|
|
return br;
|
|
}
|
|
|
|
private static String writePlainTableLine(ValueSource valueSource, int loadIndex, int loadSize) {
|
|
StringBuilder sb = new StringBuilder("{");
|
|
|
|
for (int rpmIndex = 0; rpmIndex < loadSize; rpmIndex++) {
|
|
sb.append(String.format("%3.3f", valueSource.getValue(loadIndex, rpmIndex)) + ",\t");
|
|
}
|
|
sb.append("},\n");
|
|
|
|
return sb.toString();
|
|
}
|
|
|
|
private static String writeTableLine(CurveData loadBins, CurveData rpmBins, ValueSource valueSource, int loadIndex) {
|
|
StringBuilder sb = new StringBuilder("{");
|
|
|
|
sb.append("/* " + loadIndex + " " + String.format("%3.3f", loadBins.getRawData()[loadIndex]) + "\t*/");
|
|
for (int rpmIndex = 0; rpmIndex < rpmBins.getRawData().length; rpmIndex++) {
|
|
sb.append("/* " + rpmIndex + " " + rpmBins.getRawData()[rpmIndex] + "*/" + String.format("%3.3f", valueSource.getValue(loadIndex, rpmIndex)) + ",\t");
|
|
}
|
|
sb.append("},\n");
|
|
|
|
return sb.toString();
|
|
}
|
|
|
|
@NotNull
|
|
public static String getCopyMethodBody(String tableReference, IniFileModel model, String tableName) {
|
|
String xRpmBinsName = model.getXBin(tableName);
|
|
String yLoadBinsName = model.getYBin(tableName);
|
|
|
|
String x = "\tcopyArray(" + tableReference + "LoadBins, hardCoded" + xRpmBinsName + ");\n" +
|
|
"\tcopyArray(" + tableReference + "RpmBins, hardCoded" + yLoadBinsName + ");\n" +
|
|
"\tcopyTable(" + tableReference + "Table, hardCoded" + tableName + ");\n";
|
|
return x;
|
|
}
|
|
|
|
public interface ValueSource {
|
|
float getValue(int rowIndex, int columnIndex);
|
|
}
|
|
|
|
}
|