diff --git a/src/main/java/com/rusefi/can/analysis/ByteRateOfChange.java b/src/main/java/com/rusefi/can/analysis/ByteRateOfChange.java index 908b630..7a2a008 100644 --- a/src/main/java/com/rusefi/can/analysis/ByteRateOfChange.java +++ b/src/main/java/com/rusefi/can/analysis/ByteRateOfChange.java @@ -45,7 +45,7 @@ public class ByteRateOfChange { for (ByteStatistics byteStatistics : allStats) { ByteId key = byteStatistics.key; - ps.println(dualSid(key.sid) + " byte " + key.bitIndex + " has " + byteStatistics.getUniqueValuesCount() + " unique value(s)"); + ps.println(dualSid(key.sid) + " byte " + key.getByteIndex() + " has " + byteStatistics.getUniqueValuesCount() + " unique value(s)"); } ps.close(); @@ -105,15 +105,15 @@ public class ByteRateOfChange { public static class ByteId implements Comparable { final int sid; - final int bitIndex; + final int byteIndex; - public ByteId(int sid, int bitIndex) { + public ByteId(int sid, int byteIndex) { this.sid = sid; - this.bitIndex = bitIndex; + this.byteIndex = byteIndex; } public String getLogKey() { - return dualSid(sid) + "_byte_" + bitIndex + "_bit_" + (bitIndex * 8); + return dualSid(sid) + "_byte_" + byteIndex + "_bit_" + (byteIndex * 8); } @Override @@ -121,12 +121,16 @@ public class ByteRateOfChange { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ByteId byteId = (ByteId) o; - return sid == byteId.sid && bitIndex == byteId.bitIndex; + return sid == byteId.sid && byteIndex == byteId.byteIndex; + } + + public int getByteIndex() { + return byteIndex; } @Override public int hashCode() { - return Objects.hash(sid, bitIndex); + return Objects.hash(sid, byteIndex); } @Override @@ -134,7 +138,7 @@ public class ByteRateOfChange { ByteId other = o; if (other.sid != sid) return sid - other.sid; - return bitIndex - other.bitIndex; + return byteIndex - other.byteIndex; } @Override diff --git a/src/main/java/com/rusefi/can/analysis/ByteRateOfChangeReports.java b/src/main/java/com/rusefi/can/analysis/ByteRateOfChangeReports.java index ff087d2..8191cc6 100644 --- a/src/main/java/com/rusefi/can/analysis/ByteRateOfChangeReports.java +++ b/src/main/java/com/rusefi/can/analysis/ByteRateOfChangeReports.java @@ -11,14 +11,14 @@ public class ByteRateOfChangeReports { /** * sweet baby O(n^2) */ - public static void compareEachReportAgainstAllOthers(String reportDestinationFolder, List reports) throws FileNotFoundException { + public static void compareEachReportAgainstAllOthers(String reportDestinationFolder, List reports, CanContext context) throws FileNotFoundException { for (int i = 0; i < reports.size(); i++) { for (int j = i + 1; j < reports.size(); j++) - compareTwoReports(reportDestinationFolder, reports.get(i), reports.get(j)); + compareTwoReports(reportDestinationFolder, reports.get(i), reports.get(j), context); } } - private static void compareTwoReports(String reportDestinationFolder, ByteRateOfChange.TraceReport traceReport1, ByteRateOfChange.TraceReport traceReport2) throws FileNotFoundException { + private static void compareTwoReports(String reportDestinationFolder, ByteRateOfChange.TraceReport traceReport1, ByteRateOfChange.TraceReport traceReport2, CanContext context) throws FileNotFoundException { Set allKeys = new TreeSet<>(); allKeys.addAll(traceReport1.getStatistics().keySet()); allKeys.addAll(traceReport2.getStatistics().keySet()); @@ -37,6 +37,15 @@ public class ByteRateOfChangeReports { for (ByteRateOfChange.ByteId id : allKeys) { + if (context.counterBytes.contains(id)) { + // skipping byte with a known counter + continue; + } + if (id.getByteIndex() == 7 && context.withChecksum.contains(id.sid)) { + // skipping known checksum byte + continue; + } + ByteRateOfChange.ByteStatistics s1 = traceReport1.getStatistics().computeIfAbsent(id, ByteRateOfChange.ByteStatistics::new); ByteRateOfChange.ByteStatistics s2 = traceReport2.getStatistics().computeIfAbsent(id, ByteRateOfChange.ByteStatistics::new); @@ -70,6 +79,8 @@ public class ByteRateOfChangeReports { public static void scanInputFolder(String inputFolderName, String fileNameSuffix) throws IOException { String reportDestinationFolder = createOutputFolder(inputFolderName); + CanContext context = CanContext.read(inputFolderName); + List reports = new ArrayList<>(); FolderUtil.handleFolder(inputFolderName, (simpleFileName, fullInputFileName) -> { @@ -77,7 +88,9 @@ public class ByteRateOfChangeReports { List logFileContent = CANLineReader.getReader().readFile(fullInputFileName); PerSidDump.handle(reportDestinationFolder, simpleFileName, logFileContent); + // at the moment we overwrite counter detection report after we process each file CounterScanner.scanForCounters(reportDestinationFolder, logFileContent); + ChecksumScanner.scanForChecksums(reportDestinationFolder, logFileContent); CanToMegaLogViewer.createMegaLogViewer(reportDestinationFolder, logFileContent, simpleFileName); @@ -87,7 +100,7 @@ public class ByteRateOfChangeReports { System.out.println("Processing " + reports.size() + " report(s)"); - compareEachReportAgainstAllOthers(reportDestinationFolder, reports); + compareEachReportAgainstAllOthers(reportDestinationFolder, reports, context); } static class ByteVariationDifference { diff --git a/src/main/java/com/rusefi/can/analysis/CanContext.java b/src/main/java/com/rusefi/can/analysis/CanContext.java new file mode 100644 index 0000000..9711ef3 --- /dev/null +++ b/src/main/java/com/rusefi/can/analysis/CanContext.java @@ -0,0 +1,48 @@ +package com.rusefi.can.analysis; + +import org.yaml.snakeyaml.Yaml; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class CanContext { + final Set withChecksum = new HashSet<>(); + final Map> countersMap; + + Set counterBytes = new HashSet<>(); + + private CanContext(List withChecksum, Map> countersMap) { + this.countersMap = countersMap; + this.withChecksum.addAll(withChecksum); + + for (Map.Entry> e : countersMap.entrySet()) { + int sid = e.getKey(); + Map v = e.getValue(); + + for (Map.Entry e2 : v.entrySet()) { + int bitIndex = e2.getKey(); + int size = e2.getValue(); + + if (size > 4) { + int byteIndex = bitIndex / 8; + counterBytes.add(new ByteRateOfChange.ByteId(sid, byteIndex)); + } + } + } + } + + public static CanContext read(String inputFolderName) throws FileNotFoundException { + Yaml checksum = new Yaml(); + List withChecksum = checksum.load(new FileReader(inputFolderName + File.separator + ChecksumScanner.CHECKSUM_YAML)); + + Yaml countersYaml = new Yaml(); + Map> countersMap = countersYaml.load(new FileReader(inputFolderName + File.separator + CounterScanner.COUNTERS_YAML)); + + return new CanContext(withChecksum, countersMap); + } +} diff --git a/src/main/java/com/rusefi/can/analysis/ChecksumScanner.java b/src/main/java/com/rusefi/can/analysis/ChecksumScanner.java new file mode 100644 index 0000000..5f46243 --- /dev/null +++ b/src/main/java/com/rusefi/can/analysis/ChecksumScanner.java @@ -0,0 +1,49 @@ +package com.rusefi.can.analysis; + +import com.rusefi.can.CANPacket; +import org.yaml.snakeyaml.Yaml; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ChecksumScanner { + + public static final String CHECKSUM_YAML = "checksum.yaml"; + + public static void scanForChecksums(String reportDestinationFolder, List packets) throws IOException { + Map isChecksumMap = new HashMap<>(); + + J1850_SAE_crc8_Calculator c = new J1850_SAE_crc8_Calculator(); + + for (CANPacket packet : packets) { + AtomicBoolean isChecksum = isChecksumMap.computeIfAbsent(packet.getId(), integer -> new AtomicBoolean(true)); + if (!isChecksum.get()) + continue; + byte[] data = packet.getData(); + if (data.length != 8) { + isChecksum.set(false); + continue; + } + byte checksum = c.crc8(data, 7); + isChecksum.set(data[7] == checksum); + } + + + List withChecksum = new ArrayList<>(); + + for (Map.Entry e : isChecksumMap.entrySet()) { + if (e.getValue().get()) { + Integer sid = e.getKey(); + System.out.println("Ends with checksum " + sid); + withChecksum.add(sid); + } + } + Yaml yaml = new Yaml(); + String yamlCountersReportFileName = reportDestinationFolder + File.separator + CHECKSUM_YAML; + System.out.println("Writing report to " + yamlCountersReportFileName); + yaml.dump(withChecksum, new FileWriter(yamlCountersReportFileName)); + } +} diff --git a/src/main/java/com/rusefi/can/analysis/CounterScanner.java b/src/main/java/com/rusefi/can/analysis/CounterScanner.java index c5661ab..e017455 100644 --- a/src/main/java/com/rusefi/can/analysis/CounterScanner.java +++ b/src/main/java/com/rusefi/can/analysis/CounterScanner.java @@ -7,6 +7,9 @@ import java.io.*; import java.util.*; public class CounterScanner { + + public static final String COUNTERS_YAML = "counters.yaml"; + public static void scanForCounters(String reportDestinationFolder, List packets) throws IOException { String outputFileName = reportDestinationFolder + File.separator + "counter_report.txt"; @@ -59,7 +62,7 @@ public class CounterScanner { lengthByStartIndex.put(counterWithWidth.getStart().getTotalBitIndex(), counterWithWidth.getTotalNumberOfBits()); } - String yamlCountersReportFileName = reportDestinationFolder + File.separator + "counters.yaml"; + String yamlCountersReportFileName = reportDestinationFolder + File.separator + COUNTERS_YAML; System.out.println("Writing report to " + yamlCountersReportFileName); yaml.dump(map, new FileWriter(yamlCountersReportFileName)); pw.close(); @@ -75,7 +78,7 @@ public class CounterScanner { } public int getTotalBitIndex() { - return byteId.bitIndex * 8 + bitIndex; + return byteId.byteIndex * 8 + bitIndex; } public int getSid() { @@ -83,7 +86,7 @@ public class CounterScanner { } public int getByteIndex() { - return byteId.bitIndex; + return byteId.byteIndex; } public int getBitIndex() {