REO progress - binary logs

This commit is contained in:
rusefi 2020-06-14 15:43:54 -04:00
parent 9e03655101
commit 8165ee016f
6 changed files with 208 additions and 46 deletions

View File

@ -11,14 +11,14 @@
#include "crc.h"
static const LogField fields[] = {
{tsOutputChannels.rpm, "RPM", "rpm", 0},
{tsOutputChannels.rpm, GAUGE_NAME_RPM, "rpm", 0},
{tsOutputChannels.vehicleSpeedKph, GAUGE_NAME_VVS, "kph", 0},
{tsOutputChannels.internalMcuTemperature, GAUGE_NAME_CPU_TEMP, "C", 0},
{tsOutputChannels.coolantTemperature, "CLT", "C", 1},
{tsOutputChannels.intakeAirTemperature, "IAT", "C", 1},
{tsOutputChannels.throttlePosition, "TPS", "%", 2},
{tsOutputChannels.coolantTemperature, GAUGE_NAME_CLT, "C", 1},
{tsOutputChannels.intakeAirTemperature, GAUGE_NAME_IAT, "C", 1},
{tsOutputChannels.throttlePosition, GAUGE_NAME_TPS, "%", 2},
{tsOutputChannels.pedalPosition, GAUGE_NAME_THROTTLE_PEDAL, "%", 2},
{tsOutputChannels.manifoldAirPressure, "MAP", "kPa", 1},
{tsOutputChannels.manifoldAirPressure, GAUGE_NAME_MAP, "kPa", 1},
{tsOutputChannels.airFuelRatio, GAUGE_NAME_AFR, "afr", 2},
{tsOutputChannels.vBatt, GAUGE_NAME_VBAT, "v", 2},
{tsOutputChannels.oilPressure, "Oil Press", "kPa", 0},

View File

@ -1106,16 +1106,16 @@ gaugeCategory = Sensors - Raw
[Datalog]
; Channel Label Type Format
entry = time, "Time", float, "%.3f"
entry = RPMValue, "RPM", int, "%d"
entry = time, @@GAUGE_NAME_TIME@@, float, "%.3f"
entry = RPMValue, @@GAUGE_NAME_RPM@@, int, "%d"
entry = firmwareVersion, @@GAUGE_NAME_VERSION@@, int, "%d"
entry = coolant, "CLT", float, "%.2f"
entry = intake, "IAT", float, "%.2f"
entry = coolant, @@GAUGE_NAME_CLT@@, float, "%.2f"
entry = intake, @@GAUGE_NAME_IAT@@, float, "%.2f"
entry = oilPressure, "Oil Press", float, "%.1f"
entry = TPSValue, "TPS", float, "%.2f"
entry = MAFValue, "MAF", float, "%.2f"
entry = MAPValue, "MAP", float, "%.1f"
entry = AFRValue, @@GAUGE_NAME_AFR@@, float, "%.2f"
entry = TPSValue, @@GAUGE_NAME_TPS@@, float, "%.2f"
entry = MAFValue, @@GAUGE_NAME_MAF@@, float, "%.2f"
entry = MAPValue, @@GAUGE_NAME_MAP@@, float, "%.1f"
entry = AFRValue, @@GAUGE_NAME_AFR@@, float, "%.2f"
entry = VBatt, @@GAUGE_NAME_VBAT@@, float, "%.2f"
entry = engineLoad, @@GAUGE_NAME_ENGINE_LOAD@@, float, "%.1f"
entry = ignitionAdvance, @@GAUGE_NAME_TIMING_ADVANCE@@, float, "%.2f"

View File

@ -4,6 +4,8 @@ import com.rusefi.config.FieldType;
import com.rusefi.config.generated.Fields;
import org.jetbrains.annotations.Nullable;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
import java.util.Set;
@ -28,17 +30,17 @@ public enum Sensor {
// Temperatures
INT_TEMP(GAUGE_NAME_CPU_TEMP, SensorCategory.OPERATIONS, FieldType.INT8, 10, 1, 0, 5, "C"),
CLT(GAUGE_NAME_CLT, SensorCategory.SENSOR_INPUTS, FieldType.INT16, 12, 1.0 / PACK_MULT_TEMPERATURE, -40, 150, "deg C"),
IAT("IAT", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 14, 1.0 / PACK_MULT_TEMPERATURE, -40, 150, "deg C"),
IAT(GAUGE_NAME_IAT, SensorCategory.SENSOR_INPUTS, FieldType.INT16, 14, 1.0 / PACK_MULT_TEMPERATURE, -40, 150, "deg C"),
// throttle, pedal
TPS("TPS", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 20, 1.0 / PACK_MULT_PERCENT, 0, 100, "%"), // throttle position sensor
TPS(GAUGE_NAME_TPS, SensorCategory.SENSOR_INPUTS, FieldType.INT16, 20, 1.0 / PACK_MULT_PERCENT, 0, 100, "%"), // throttle position sensor
PPS(GAUGE_NAME_THROTTLE_PEDAL, SensorCategory.SENSOR_INPUTS, FieldType.INT16, 22, 1.0 / PACK_MULT_PERCENT, 0, 100, "%"), // pedal position sensor
// air flow/mass measurement
MAF("MAF", SensorCategory.SENSOR_INPUTS, FieldType.UINT16, 26, 1.0 / PACK_MULT_VOLTAGE, 0, 5, "Volts"),
MAP("MAP", SensorCategory.SENSOR_INPUTS, FieldType.UINT16, 30, 1.0 / PACK_MULT_PRESSURE, 20, 300, "kPa"),
MAF(GAUGE_NAME_MAF, SensorCategory.SENSOR_INPUTS, FieldType.UINT16, 26, 1.0 / PACK_MULT_VOLTAGE, 0, 5, "Volts"),
MAP(GAUGE_NAME_MAP, SensorCategory.SENSOR_INPUTS, FieldType.UINT16, 30, 1.0 / PACK_MULT_PRESSURE, 20, 300, "kPa"),
AFR("A/F ratio", SensorCategory.SENSOR_INPUTS, FieldType.UINT16, 34, 1.0 / PACK_MULT_AFR, 10, 20, "afr"),
AFR(GAUGE_NAME_AFR, SensorCategory.SENSOR_INPUTS, FieldType.UINT16, 34, 1.0 / PACK_MULT_AFR, 10, 20, "afr"),
VBATT(GAUGE_NAME_VBAT, SensorCategory.SENSOR_INPUTS, FieldType.UINT16, 38, 1.0 / PACK_MULT_VOLTAGE, 4, 18, "Volts"),
oilPressure("Oil Pressure", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 40, 1.0 / PACK_MULT_PRESSURE, 0, 5, "X"),
@ -47,7 +49,7 @@ public enum Sensor {
// fuel math
CHARGE_AIR_MASS("airmass", SensorCategory.OPERATIONS, FieldType.UINT16, 44, 0.001, 0, 3, "g/cyl"),
crankingFuel(GAUGE_NAME_FUEL_CRANKING, SensorCategory.FUEL, FieldType.UINT16, 46, 1.0 / PACK_MULT_MS, 0, 30, "ms"),
TARGET_AFR("A/F target", SensorCategory.OPERATIONS, FieldType.INT16, 48, 1.0 / PACK_MULT_AFR, 10, 20, "afr"),
TARGET_AFR(GAUGE_NAME_TARGET_AFR, SensorCategory.OPERATIONS, FieldType.INT16, 48, 1.0 / PACK_MULT_AFR, 10, 20, "afr"),
baseFuel(Fields.GAUGE_NAME_FUEL_BASE, SensorCategory.FUEL, FieldType.UINT16, 50, 1.0 / PACK_MULT_MS, 0, 30, "ms"),
runningFuel(GAUGE_NAME_FUEL_RUNNING, SensorCategory.FUEL, FieldType.UINT16, 52, 1.0 / PACK_MULT_MS, 0, 15, "ms"),
actualLastInjection(GAUGE_NAME_FUEL_LAST_INJECTION, SensorCategory.FUEL, FieldType.UINT16, 54, 1.0 / PACK_MULT_MS, 0, 30, "ms"),
@ -59,7 +61,7 @@ public enum Sensor {
injectorLagMs(GAUGE_NAME_INJECTOR_LAG, SensorCategory.FUEL, FieldType.UINT16, 62, 1.0 / PACK_MULT_MS, 0, 15, "ms"),
iatCorrection(GAUGE_NAME_FUEL_IAT_CORR, SensorCategory.FUEL, FieldType.INT16, 64, 1.0 / PACK_MULT_PERCENT, 0, 5, "ratio"),
cltCorrection(GAUGE_NAME_FUEL_CLT_CORR, SensorCategory.FUEL, FieldType.INT16, 66, 1.0 / PACK_MULT_PERCENT, 0, 5, "ratio"),
fuelPidCorrection("Fuel PID", SensorCategory.FUEL, FieldType.INT16, 70, 1.0 / PACK_MULT_MS, -2, 2, "ms"),
fuelPidCorrection("Fuel PID", SensorCategory.FUEL, FieldType.INT16, 70, 1.0 / PACK_MULT_MS, -2, 2, "ms"),
// Wall model AE
wallFuelAmount(GAUGE_NAME_FUEL_WALL_AMOUNT, SensorCategory.FUEL, FieldType.UINT16, 72, 1.0 / PACK_MULT_MS, 0, 20, "ms"),
@ -234,4 +236,21 @@ public enum Sensor {
public double translateValue(double value) {
return value;
}
public void writeToLog(DataOutputStream dos, double value) throws IOException {
switch (type) {
case FLOAT:
dos.writeFloat((float) value);
return;
case UINT16:
case INT16:
dos.writeShort((int) value);
return;
case INT:
dos.writeInt((int) value);
return;
default:
throw new UnsupportedOperationException("Type " + type);
}
}
}

View File

@ -1,16 +1,34 @@
package com.rusefi.sensor_logs;
import com.rusefi.FileLog;
import com.rusefi.config.generated.Fields;
import com.rusefi.core.Sensor;
import com.rusefi.core.SensorCentral;
import com.rusefi.rusEFIVersion;
import java.io.*;
import java.util.Date;
import java.util.function.Function;
public class BinarySensorLog extends SensorLog {
private BufferedWriter stream;
private final Function<Sensor, Double> valueProvider;
private final Sensor[] sensors;
private DataOutputStream stream;
public static void main(String[] args) {
BinarySensorLog l = new BinarySensorLog();
l.writeSensorLogLine();
private int counter;
public BinarySensorLog() {
this(new Function<Sensor, Double>() {
@Override
public Double apply(Sensor sensor) {
return SensorCentral.getInstance().getValue(sensor);
}
}, SensorLogger.SENSORS);
}
public BinarySensorLog(Function<Sensor, Double> valueProvider, Sensor... sensors) {
this.valueProvider = valueProvider;
this.sensors = sensors;
}
@Override
@ -25,36 +43,35 @@ public class BinarySensorLog extends SensorLog {
String fileName = FileLog.DIR + "rusEFI_gauges_" + FileLog.getDate() + ".mlg";
try {
stream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName)));
stream = new DataOutputStream(new FileOutputStream(fileName));
} catch (IOException e) {
e.printStackTrace();
stream = null;
}
writeHeader();
}
if (stream != null) {
try {
for (char c : "MLVLG\0".toCharArray()) {
stream.write(c);
}
stream.write(0);
stream.write(1);
for (Sensor sensor : SensorLogger.SENSORS) {
String name = SensorLogger.getSensorName(sensor, 0);
String unit = sensor.getUnits();
writeLine(stream, name, 34);
writeLine(stream, unit, 11);
stream.write(0);
stream.write(0);
stream.write(0);
stream.write(0);
stream.write(counter++);
stream.writeShort((int) (System.currentTimeMillis() * 100));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
for (Sensor sensor : sensors) {
double value = valueProvider.apply(sensor);
sensor.writeToLog(dos, value);
}
stream.close();
byte[] byteArray = baos.toByteArray();
byte checkSum = 0;
for (int i = 0; i < byteArray.length; i++) {
checkSum += byteArray[i];
}
stream.write(byteArray);
stream.write(checkSum);
} catch (IOException e) {
e.printStackTrace();
@ -62,7 +79,89 @@ public class BinarySensorLog extends SensorLog {
}
}
private void writeLine(BufferedWriter stream, String name, int length) throws IOException {
private void writeHeader() {
try {
String headerText = "\"rusEFI " + rusEFIVersion.CONSOLE_VERSION + "\"\n" +
"\"Capture Date: " + new Date() + "\"\n";
for (char c : "MLVLG\0".toCharArray()) {
stream.write(c);
}
int fieldsDataSize = 0;
for (Sensor sensor : sensors) {
fieldsDataSize += sensor.getType().getStorageSize();
}
// 0006h Format version = 01
stream.write(0);
stream.write(1);
// 0008h Timestamp
stream.writeInt(0);
// 000ch
int offsetToText = Fields.MLQ_HEADER_SIZE + Fields.MLQ_FIELD_HEADER_SIZE * sensors.length;
stream.writeShort(offsetToText);
stream.writeShort(0); // reserved?
// 0010h = offset_to_data
stream.writeShort(offsetToText + headerText.length());
// 0012h
stream.writeShort(fieldsDataSize);
// 0014h number of fields
stream.writeShort(sensors.length);
for (Sensor sensor : sensors) {
String name = SensorLogger.getSensorName(sensor, 0);
String unit = sensor.getUnits();
// 0000h
stream.write(getSensorTypeValue(sensor));
// 0001h
writeLine(stream, name, 34);
// 0023h
writeLine(stream, unit, 11);
// 002Eh scale
stream.writeFloat(1); // todo: multiplier?
// 0032h zeroes
stream.writeInt(0);
// 0036h precision
stream.write(2);
}
writeLine(stream, headerText, 0);
} catch (IOException e) {
e.printStackTrace();
}
}
private int getSensorTypeValue(Sensor sensor) {
switch (sensor.getType()) {
case UINT16:
return 2;
case INT16:
return 3;
case INT:
return 4;
case FLOAT:
return 7;
default:
throw new UnsupportedOperationException("" + sensor.getType());
}
}
public void close() {
close(stream);
}
public static void close(Closeable closeable) {
try {
closeable.close();
} catch (IOException e) {
// ignoring
}
}
private void writeLine(DataOutputStream stream, String name, int length) throws IOException {
for (int i = 0; i < name.length(); i++) {
stream.write(name.charAt(i));
}

View File

@ -0,0 +1,44 @@
package com.rusefi.sensor_logs;
import com.rusefi.core.Sensor;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
public class BinarySensorLogSandbox {
public static void main(String[] args) {
Map<Sensor, Double> values = new HashMap<>();
Function<Sensor, Double> valueProvider = sensor -> {
Double result = values.get(sensor);
Objects.requireNonNull(result, "value for sensor");
return result;
};
BinarySensorLog l = new BinarySensorLog(valueProvider,
Sensor.TIME_SECONDS,
Sensor.RPM,
Sensor.FIRMWARE_VERSION,
Sensor.CLT);
values.put(Sensor.TIME_SECONDS, 1.0);
values.put(Sensor.RPM, 0.0);
values.put(Sensor.FIRMWARE_VERSION, 20200101.0);
values.put(Sensor.CLT, 29.0);
l.writeSensorLogLine();
for (int i = 2; i < 10; i++) {
values.put(Sensor.TIME_SECONDS, (double) i);
values.put(Sensor.RPM, 180.0 + i);
values.put(Sensor.FIRMWARE_VERSION, 20200101.0);
values.put(Sensor.CLT, 39.0);
l.writeSensorLogLine();
}
l.close();
}
}

View File

@ -28,7 +28,7 @@ Field format:
0001h = name (34 bytes)
0023h = units (11 bytes)
002Eh = scale (4 bytes) = float
0032h = zeroes (4 bytes)
0032h = shift (4 bytes) = float, usually zero for rusEFI
0036h = precision (1 byte) 1="%.1f", 2="%.2f",...
} fields[num_fields]
@ -41,5 +41,5 @@ Data format:
{
0000h = "counter-ish" (4 bytes)
0004h = packed fields data (see type_and_size)
..... = crc (1 byte)
..... = checksum just the sum of all packed fields bytes (1 byte)
} records[]