From f367a16570a6902a6ceea9a89f716f0a9a61875c Mon Sep 17 00:00:00 2001 From: rusefillc Date: Wed, 22 Jun 2022 02:05:04 -0400 Subject: [PATCH] progress --- .../com/rusefi/can/reader/dbc/DbcPacket.java | 4 + .../rusefi/sensor_logs/BinaryLogEntry.java | 14 ++ .../rusefi/sensor_logs/BinarySensorLog.java | 156 ++++++++++++++++++ .../java/com/rusefi/sensor_logs/Fields.java | 6 + .../can/reader/impl/TrcToMlqSandbox.java | 71 ++++++++ 5 files changed, 251 insertions(+) create mode 100644 src/main/java/com/rusefi/sensor_logs/BinaryLogEntry.java create mode 100644 src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java create mode 100644 src/main/java/com/rusefi/sensor_logs/Fields.java create mode 100644 src/test/java/com/rusefi/can/reader/impl/TrcToMlqSandbox.java diff --git a/src/main/java/com/rusefi/can/reader/dbc/DbcPacket.java b/src/main/java/com/rusefi/can/reader/dbc/DbcPacket.java index a79387a..8dddb83 100644 --- a/src/main/java/com/rusefi/can/reader/dbc/DbcPacket.java +++ b/src/main/java/com/rusefi/can/reader/dbc/DbcPacket.java @@ -21,6 +21,10 @@ public class DbcPacket { return name; } + public List getFields() { + return fields; + } + @Override public String toString() { return "DbcPacket{" + diff --git a/src/main/java/com/rusefi/sensor_logs/BinaryLogEntry.java b/src/main/java/com/rusefi/sensor_logs/BinaryLogEntry.java new file mode 100644 index 0000000..9497e7a --- /dev/null +++ b/src/main/java/com/rusefi/sensor_logs/BinaryLogEntry.java @@ -0,0 +1,14 @@ +package com.rusefi.sensor_logs; + +import java.io.DataOutputStream; +import java.io.IOException; + +public interface BinaryLogEntry { + String getName(); + + String getUnit(); + + int getByteSize(); + + void writeToLog(DataOutputStream dos, double value) throws IOException; +} diff --git a/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java b/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java new file mode 100644 index 0000000..8473ec8 --- /dev/null +++ b/src/main/java/com/rusefi/sensor_logs/BinarySensorLog.java @@ -0,0 +1,156 @@ +package com.rusefi.sensor_logs; + +import java.io.*; +import java.util.*; +import java.util.function.Function; + +/** + * MLV .mlq binary log file + *

+ * Andrey Belomutskiy, (c) 2013-2020 + */ +public class BinarySensorLog implements SensorLog { + private final Function valueProvider; + private final Collection entries; + private DataOutputStream stream; + + private String fileName; + + private int counter; + + public BinarySensorLog(Function valueProvider, Collection sensors) { + this.valueProvider = valueProvider; + this.entries = Objects.requireNonNull(sensors, "entries"); + } + + @Override + public double getSecondsSinceFileStart() { + throw new UnsupportedOperationException(); + } + + @Override + public void writeSensorLogLine() { + if (stream == null) { + fileName = "gauges_" + ".mlg"; + + try { + stream = new DataOutputStream(new FileOutputStream(fileName)); + writeHeader(); + } catch (Throwable e) { + e.printStackTrace(); + stream = null; + } + } + + if (stream != null) { + try { + stream.write(0); + stream.write(counter++); + stream.writeShort((int) (System.currentTimeMillis() * 100)); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + + for (T sensor : entries) { + double value = valueProvider.apply(sensor); + sensor.writeToLog(dos, value); + } + + byte[] byteArray = baos.toByteArray(); + byte checkSum = 0; + for (byte b : byteArray) { + checkSum += b; + } + stream.write(byteArray); + stream.write(checkSum); + + if (counter % 20 == 0) { + // for not flush on each block of data but still flush + stream.flush(); + } + + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private void writeHeader() throws IOException { + String headerText = "\"rusEFI " + "sdsr" + "\"\n" + + "\"Capture Date: " + new Date() + "\"\n"; + + for (char c : "MLVLG\0".toCharArray()) { + stream.write(c); + } + + int fieldsDataSize = 0; + for (BinaryLogEntry entry : entries) { + fieldsDataSize += entry.getByteSize(); + } + + // 0006h Format version = 01 + stream.write(0); + stream.write(1); + // 0008h Timestamp + stream.writeInt((int) (System.currentTimeMillis() / 1000)); + // 000ch + int offsetToText = Fields.MLQ_HEADER_SIZE + Fields.MLQ_FIELD_HEADER_SIZE * entries.size(); + 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(entries.size()); + + for (BinaryLogEntry sensor : entries) { + String name = sensor.getName(); + String unit = sensor.getUnit(); + + // 0000h + stream.write(sensor.getByteSize()); + // 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); + } + if (stream.size() != offsetToText) + throw new IllegalStateException("We are doing something wrong :( stream.size=" + stream.size()); + writeLine(stream, headerText, headerText.length()); + } + + @Override + public void close() { + close(stream); + stream = null; + } + + public static void close(Closeable closeable) { + try { + if (closeable != null) { + closeable.close(); + } + } catch (IOException e) { + // ignoring + } + } + + public String getFileName() { + return fileName; + } + + private void writeLine(DataOutputStream stream, String name, int length) throws IOException { + for (int i = 0; i < Math.min(name.length(), length); i++) { + stream.write(name.charAt(i)); + } + for (int i = name.length(); i < length; i++) + stream.write(0); + } +} diff --git a/src/main/java/com/rusefi/sensor_logs/Fields.java b/src/main/java/com/rusefi/sensor_logs/Fields.java new file mode 100644 index 0000000..223aba8 --- /dev/null +++ b/src/main/java/com/rusefi/sensor_logs/Fields.java @@ -0,0 +1,6 @@ +package com.rusefi.sensor_logs; + +public class Fields { + public static final int MLQ_FIELD_HEADER_SIZE = 55; + public static final int MLQ_HEADER_SIZE = 22; +} diff --git a/src/test/java/com/rusefi/can/reader/impl/TrcToMlqSandbox.java b/src/test/java/com/rusefi/can/reader/impl/TrcToMlqSandbox.java new file mode 100644 index 0000000..be480f4 --- /dev/null +++ b/src/test/java/com/rusefi/can/reader/impl/TrcToMlqSandbox.java @@ -0,0 +1,71 @@ +package com.rusefi.can.reader.impl; + +import com.rusefi.can.CANPacket; +import com.rusefi.can.reader.dbc.DbcField; +import com.rusefi.can.reader.dbc.DbcFile; +import com.rusefi.can.reader.dbc.DbcPacket; +import com.rusefi.sensor_logs.BinaryLogEntry; +import com.rusefi.sensor_logs.BinarySensorLog; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +import static com.rusefi.can.reader.impl.ParseDBC.VAG_MOTOR_1; + +public class TrcToMlqSandbox { + public static void main(String[] args) throws IOException { + DbcFile dbc = new DbcFile(); + { + BufferedReader reader = new BufferedReader(new StringReader(VAG_MOTOR_1)); + dbc.read(reader); + } + + List entries = new ArrayList<>(); + for (DbcPacket packet : dbc.packets) { + for (DbcField field : packet.getFields()) { + entries.add(new BinaryLogEntry() { + @Override + public String getName() { + return field.getName(); + } + + @Override + public String getUnit() { + return "x"; + } + + @Override + public int getByteSize() { + return 4; + } + + @Override + public void writeToLog(DataOutputStream dos, double value) throws IOException { + dos.writeFloat((float) value); + } + }); + + } + } + + PcanTrcReader reader = new PcanTrcReader(); + List packets = reader.readFile("C:\\stuff\\rusefi_documentation\\OEM-Docs\\VAG\\2006-Passat-B6\\passat-b6-stock-ecu-ecu-ptcan-not-running-pedal-up-and-down.trc"); + System.out.println(packets.size() + " packets"); + + + BinarySensorLog log = new BinarySensorLog(new Function() { + @Override + public Double apply(BinaryLogEntry o) { + System.out.println("apply"); + return null; + } + }, entries); + + + } +}