REO progress - binary logs
This commit is contained in:
parent
9e03655101
commit
8165ee016f
|
@ -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},
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
|
@ -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[]
|
||||
|
|
Loading…
Reference in New Issue