can-log-tools/src/main/java/com/rusefi/can/analysis/ByteRateOfChange.java

226 lines
8.1 KiB
Java
Raw Normal View History

2022-11-12 09:29:20 -08:00
package com.rusefi.can.analysis;
2022-11-10 15:12:02 -08:00
2022-11-12 09:29:20 -08:00
import com.rusefi.can.CANPacket;
import com.rusefi.mlv.LoggingContext;
import com.rusefi.mlv.LoggingStrategy;
2022-11-10 20:38:46 -08:00
import com.rusefi.sensor_logs.BinaryLogEntry;
import com.rusefi.sensor_logs.BinarySensorLog;
2022-11-10 15:12:02 -08:00
2022-11-12 20:00:51 -08:00
import java.io.*;
2022-11-10 15:12:02 -08:00
import java.util.*;
public class ByteRateOfChange {
2022-11-12 18:12:54 -08:00
static class TraceFileMetaIndex {
2023-07-30 16:52:39 -07:00
final HashMap<ByteId, ByteStatistics> statistics = new HashMap<>();
2022-11-10 15:12:02 -08:00
2023-07-30 16:52:39 -07:00
final Set<Integer> SIDs = new HashSet<>();
2022-11-12 18:12:54 -08:00
}
2022-11-12 10:07:13 -08:00
2022-11-12 18:12:54 -08:00
public static TraceReport process(String reportDestinationFolder, String simpleFileName, List<CANPacket> packets) throws IOException {
TraceFileMetaIndex traceFileMetaIndex = calculateByteStatistics(packets);
2022-11-12 20:00:51 -08:00
writeByteReport(reportDestinationFolder, simpleFileName, traceFileMetaIndex);
TraceReport traceReport = new TraceReport(packets, simpleFileName, traceFileMetaIndex.statistics);
2022-11-14 19:03:41 -08:00
traceReport.createMegaLogViewer(traceFileMetaIndex.SIDs);
2022-11-12 20:00:51 -08:00
return traceReport;
}
private static void writeByteReport(String reportDestinationFolder, String simpleFileName, TraceFileMetaIndex traceFileMetaIndex) throws FileNotFoundException {
2022-11-12 18:12:54 -08:00
List<ByteStatistics> allStats = new ArrayList<>(traceFileMetaIndex.statistics.values());
2022-11-10 15:12:02 -08:00
allStats.sort((o1, o2) -> o2.getUniqueValues() - o1.getUniqueValues());
2022-11-12 20:00:51 -08:00
// System.out.println(allStats);
2022-11-10 15:12:02 -08:00
2022-11-12 20:00:51 -08:00
writeByteReport(reportDestinationFolder, simpleFileName, allStats);
}
private static void writeByteReport(String reportDestinationFolder, String simpleFileName, List<ByteStatistics> allStats) throws FileNotFoundException {
String outputFileName = reportDestinationFolder + File.separator + simpleFileName + ".txt";
System.out.println("Wring byte report to " + outputFileName);
PrintStream ps = new PrintStream(new FileOutputStream(outputFileName, false));
2022-11-10 15:12:02 -08:00
for (ByteStatistics byteStatistics : allStats) {
ByteId key = byteStatistics.key;
2022-11-12 20:00:51 -08:00
ps.println(dualSid(key.sid) + " byte " + key.index + " has " + byteStatistics.getUniqueValues() + " unique value(s)");
2022-11-10 15:12:02 -08:00
}
2022-11-10 16:23:51 -08:00
ps.close();
2022-11-10 15:12:02 -08:00
}
2022-11-12 18:12:54 -08:00
private static TraceFileMetaIndex calculateByteStatistics(List<CANPacket> packets) {
TraceFileMetaIndex traceFileMetaIndex = new TraceFileMetaIndex();
for (CANPacket packet : packets) {
traceFileMetaIndex.SIDs.add(packet.getId());
2022-11-12 20:00:51 -08:00
for (int byteIndex = 0; byteIndex < packet.getData().length; byteIndex++) {
ByteId key = new ByteId(packet.getId(), byteIndex);
2022-11-12 18:12:54 -08:00
ByteStatistics stats = traceFileMetaIndex.statistics.computeIfAbsent(key, byteId -> new ByteStatistics(key));
2022-11-12 20:00:51 -08:00
stats.uniqueValues.add((int) packet.getData()[byteIndex]);
2022-11-12 18:12:54 -08:00
}
}
return traceFileMetaIndex;
}
private static double getDurationMs(List<CANPacket> packets) {
return packets.isEmpty() ? 0 : packets.get(packets.size() - 1).getTimeStamp() - packets.get(0).getTimeStamp();
}
2022-11-10 15:12:02 -08:00
public static String dualSid(int sid) {
2022-11-12 10:39:32 -08:00
return dualSid(sid, "/");
}
public static String dualSid(int sid, String separator) {
return String.format("%d%s0x%x", sid, separator, sid);
2022-11-10 15:12:02 -08:00
}
2022-11-12 09:29:20 -08:00
public static class ByteStatistics {
2022-11-10 15:12:02 -08:00
HashSet<Integer> uniqueValues = new HashSet<>();
private final ByteId key;
public ByteStatistics(ByteId key) {
this.key = key;
}
public int getUniqueValues() {
return uniqueValues.size();
}
@Override
public String toString() {
return "ByteStatistics{" +
"counter=" + uniqueValues.size() +
", key=" + key +
'}';
}
}
2023-01-01 23:08:45 -08:00
public static class ByteId implements Comparable {
2022-11-10 15:12:02 -08:00
final int sid;
final int index;
public ByteId(int sid, int index) {
this.sid = sid;
this.index = index;
}
2023-01-11 13:20:44 -08:00
public String getLogKey() {
2022-11-11 23:12:28 -08:00
return dualSid(sid) + "_byte_" + index + "_bit_" + (index * 8);
2022-11-11 22:53:31 -08:00
}
2022-11-10 15:12:02 -08:00
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ByteId byteId = (ByteId) o;
return sid == byteId.sid && index == byteId.index;
}
@Override
public int hashCode() {
return Objects.hash(sid, index);
}
2023-01-01 23:08:45 -08:00
@Override
public int compareTo(Object o) {
ByteId other = (ByteId) o;
if (other.sid != sid)
return sid - other.sid;
return index - other.index;
}
2022-11-10 15:12:02 -08:00
@Override
public String toString() {
2022-11-11 23:12:28 -08:00
return getLogKey();
2022-11-10 15:12:02 -08:00
}
}
2022-11-10 16:23:51 -08:00
public static class TraceReport extends HashMap<ByteId, ByteStatistics> {
2022-11-12 18:12:54 -08:00
private final List<CANPacket> packets;
2022-11-10 16:23:51 -08:00
private final String simpleFileName;
private final HashMap<ByteId, ByteStatistics> statistics;
2022-11-12 10:07:13 -08:00
private final double durationMs;
2022-11-10 16:23:51 -08:00
2022-11-12 18:12:54 -08:00
public TraceReport(List<CANPacket> packets, String simpleFileName, HashMap<ByteId, ByteStatistics> statistics) {
this.packets = packets;
2022-11-10 16:23:51 -08:00
this.simpleFileName = simpleFileName;
this.statistics = statistics;
2022-11-12 18:12:54 -08:00
this.durationMs = getDurationMs(packets);
2022-11-12 09:29:20 -08:00
}
String getSummary() {
2022-11-12 20:00:51 -08:00
return getSimpleFileName() + " (duration=" + (int) (durationMs / 1000) + "secs)";
2022-11-10 16:23:51 -08:00
}
public String getSimpleFileName() {
return simpleFileName;
}
public HashMap<ByteId, ByteStatistics> getStatistics() {
return statistics;
}
2022-11-10 20:38:46 -08:00
2022-11-14 19:03:41 -08:00
public void createMegaLogViewer(Set<Integer> SIDs) {
List<BinaryLogEntry> entries = new ArrayList<>();
2022-11-10 20:38:46 -08:00
for (ByteId key : statistics.keySet()) {
2022-11-14 19:03:41 -08:00
entries.add(BinaryLogEntry.createFloatLogEntry(key.getLogKey(), Integer.toBinaryString(key.sid)));
}
for (Integer sid : SIDs) {
for (int i = 0; i < 7; i++) {
2022-11-16 22:36:47 -08:00
{
String twoBytesKey = getTwoBytesKeyM(sid, i);
entries.add(BinaryLogEntry.createFloatLogEntry(twoBytesKey, Integer.toBinaryString(sid)));
}
{
String twoBytesKey = getTwoBytesKeyL(sid, i);
entries.add(BinaryLogEntry.createFloatLogEntry(twoBytesKey, Integer.toBinaryString(sid)));
}
2022-11-14 19:03:41 -08:00
}
2022-11-10 20:38:46 -08:00
}
2022-11-11 22:53:31 -08:00
LoggingContext context = new LoggingContext();
2022-11-14 19:03:41 -08:00
BinarySensorLog<BinaryLogEntry> log = context.getBinaryLogEntryBinarySensorLog(entries, simpleFileName + LoggingStrategy.MLG);
2022-11-11 22:53:31 -08:00
2022-11-12 17:59:47 -08:00
context.writeLogContent(packets, log, packetContent -> {
2022-11-14 19:03:41 -08:00
byte[] bytes = packetContent.getData();
for (int i = 0; i < bytes.length; i++) {
int value = bytes[i] & 0xFF;
int sid = packetContent.getId();
{
String name = new ByteId(sid, i).getLogKey();
context.currentSnapshot.put(name, (double) value);
}
{
if (i < bytes.length - 1) {
int value2 = bytes[i + 1] & 0xFF;
2022-11-16 22:36:47 -08:00
{
String name = getTwoBytesKeyM(sid, i);
context.currentSnapshot.put(name, (double) value2 * 256 + value);
}
{
String name = getTwoBytesKeyL(sid, i);
context.currentSnapshot.put(name, (double) value2 + value * 256);
}
2022-11-14 19:03:41 -08:00
}
}
2022-11-11 22:53:31 -08:00
}
return true;
});
2022-11-10 20:38:46 -08:00
}
2022-11-10 16:23:51 -08:00
}
2022-11-14 19:03:41 -08:00
2022-11-16 22:36:47 -08:00
private static String getTwoBytesKeyM(Integer sid, int i) {
return dualSid(sid) + "__" + i + "_" + (i + 1);
2022-11-14 19:03:41 -08:00
}
2022-11-16 22:36:47 -08:00
private static String getTwoBytesKeyL(Integer sid, int i) {
return dualSid(sid) + "__" + (i + 1) + "_" + i;
2023-01-01 23:08:45 -08:00
}
}