mirror of https://github.com/FOME-Tech/fome-fw.git
log output misc
This commit is contained in:
parent
094b90f6de
commit
24e06bb781
|
@ -9,10 +9,8 @@ import com.rusefi.config.generated.Fields;
|
|||
import com.rusefi.core.Sensor;
|
||||
import com.rusefi.core.SensorCentral;
|
||||
import com.rusefi.io.LinkManager;
|
||||
import com.rusefi.stream.LogicdataStreamFile;
|
||||
import com.rusefi.stream.StreamFile;
|
||||
import com.rusefi.stream.TSHighSpeedLog;
|
||||
import com.rusefi.stream.VcdStreamFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -58,8 +56,6 @@ public class BinaryProtocolLogger {
|
|||
if (!compositeLogs.isEmpty())
|
||||
return;
|
||||
compositeLogs.addAll(Arrays.asList(
|
||||
new VcdStreamFile(getFileName("rusEFI_trigger_log_", ".vcd")),
|
||||
new LogicdataStreamFile(getFileName("rusEFI_trigger_log_", ".logicdata")),
|
||||
new TSHighSpeedLog(getFileName("rusEFI_trigger_log_"))
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
package com.rusefi.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class LogicdataOutputStream {
|
||||
private final OutputStream outputStream;
|
||||
|
||||
public LogicdataOutputStream(OutputStream outputStream) {
|
||||
this.outputStream = outputStream;
|
||||
}
|
||||
|
||||
public void writeDouble(double value) throws IOException {
|
||||
if (value == 0.0) {
|
||||
writeByte(0);
|
||||
} else {
|
||||
writeByte(8);
|
||||
// doubles are saved little-endian, sorry Java :)
|
||||
ByteBuffer bb = ByteBuffer.allocate(8);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
bb.putDouble(value);
|
||||
bb.rewind();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
writeByte(bb.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is the main secret of this format! :)
|
||||
public void writeVarLength(long value) throws IOException {
|
||||
if (value < 0 || value > 0xFFFFFFFFL) {
|
||||
writeAs(value, 8);
|
||||
} else if (value == 0) {
|
||||
writeByte(0);
|
||||
} else if (value <= 0xff) {
|
||||
writeAs(value, 1);
|
||||
} else if (value <= 0xffff) {
|
||||
writeAs(value, 2);
|
||||
} else if (value <= 0xffffff) {
|
||||
writeAs(value, 3);
|
||||
} else {
|
||||
writeAs(value, 4);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAs(long value, int numBytes) throws IOException {
|
||||
if (value == 0) {
|
||||
writeByte(0);
|
||||
} else {
|
||||
writeByte(numBytes);
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
writeByte((byte) ((value >> (i * 8)) & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
outputStream.flush();
|
||||
}
|
||||
|
||||
public void writeByte(int i) throws IOException {
|
||||
outputStream.write(i);
|
||||
}
|
||||
|
||||
void writeString(String str) throws IOException {
|
||||
writeVarLength(str.length());
|
||||
for (char c : str.toCharArray()) {
|
||||
writeByte(c);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,520 +0,0 @@
|
|||
package com.rusefi.stream;
|
||||
|
||||
import com.rusefi.composite.CompositeEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Support for Saleae .logicdata format.
|
||||
* (c) andreika 2020
|
||||
* <p>
|
||||
* Jun 7 status: this code mostly works but it needs more testing
|
||||
*
|
||||
* @see LogicdataStreamFileSandbox
|
||||
*/
|
||||
public class LogicdataStreamFile extends StreamFile {
|
||||
|
||||
private static final int frequency = 1000000;
|
||||
|
||||
private static final int frequencyDivided = frequency / 10;
|
||||
|
||||
private static final char magic = 0x7f;
|
||||
private static final char version = 0x13;
|
||||
private static final String title = "Data save2";
|
||||
|
||||
private static final int BLOCK = 0x18;
|
||||
private static final int CHANNEL_BLOCK = 0x16;
|
||||
private static final int SUB = 0x54;
|
||||
|
||||
private static final int FLAG_NOTEMPTY = 2;
|
||||
private static final int FLAG_NOTEMPTY_LONG = 3;
|
||||
private static final int FLAG_EMPTY = 5;
|
||||
|
||||
private static final long RECORD_FIRST = 1;
|
||||
private static final long RECORD_NEXT = 2;
|
||||
|
||||
//looks these magic numbers are version-specific
|
||||
private static final int LOGIC4 = 0x40FD;
|
||||
private static final int LOGIC8 = 0x673B;
|
||||
private static final int LOGIC1 = 0x07BD;
|
||||
private static final int LOGIC16 = 0x533f;
|
||||
|
||||
private static final int [] CHANNEL_FLAGS = {
|
||||
0x13458b, 0x0000ff, 0x00a0f9, 0x00ffff, 0x00ff00, 0xff0000, 0xf020a0, 0x000000,
|
||||
};
|
||||
|
||||
private static final long SIGN_FLAG = 0x80000000L;
|
||||
|
||||
private static final int numChannels = 16;
|
||||
private static final int reservedDurationInSamples = 10;
|
||||
private static int realDurationInSamples = 0;
|
||||
private static int scaledDurationInSamples = 0;
|
||||
|
||||
private final String fileName;
|
||||
private final List<CompositeEvent> eventsBuffer = new ArrayList<>();
|
||||
|
||||
private static final String [] channelNames = {
|
||||
"Primary", "Secondary", "Trg", "Sync", "Coil", "Injector", "Channel 6", "Channel 7",
|
||||
"Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15"
|
||||
};
|
||||
|
||||
|
||||
public LogicdataStreamFile(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
/*
|
||||
public static void writeLogicdata(List<CompositeEvent> events, OutputStream stream) throws IOException {
|
||||
LogicdataStreamFile saver = new LogicdataStreamFile();
|
||||
saver.stream = stream;
|
||||
saver.writeHeader();
|
||||
saver.appendEvents(events);
|
||||
saver.close();
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public void append(List<CompositeEvent> events) {
|
||||
try {
|
||||
if (stream == null) {
|
||||
stream = new LogicdataOutputStream(Files.newOutputStream(Paths.get(fileName)));
|
||||
writeHeader();
|
||||
}
|
||||
eventsBuffer.addAll(events);
|
||||
} catch (IOException e) {
|
||||
// ignoring this one
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* this file format is not streaming, we have to write everything at once
|
||||
*/
|
||||
private void writeEvents(List<CompositeEvent> events) throws IOException {
|
||||
// we need at least 2 records
|
||||
if (events == null || events.size() < 2)
|
||||
return;
|
||||
long firstRecordTs = events.get(0).getTimestamp();
|
||||
long lastRecordTs = events.get(events.size() - 1).getTimestamp();
|
||||
// we don't know the total duration, so we create a margin after the last record which equals to the duration of the first event
|
||||
// TODO: why do we jump from timestamps to samples?
|
||||
realDurationInSamples = (int)(lastRecordTs + firstRecordTs);
|
||||
scaledDurationInSamples = realDurationInSamples / 4;
|
||||
|
||||
writeChannelDataHeader();
|
||||
|
||||
// the initial state should have zero timestamp
|
||||
if (events.get(0).getTimestamp() > 0)
|
||||
events.add(0, new CompositeEvent(0, false, false, false, false, false, false));
|
||||
|
||||
// we need to split the combined events into separate channels
|
||||
for (int ch = 0; ch < numChannels; ch++) {
|
||||
boolean useLongDeltas = false;
|
||||
List<Long> chDeltas = new ArrayList<>();
|
||||
int chPrevState = -1, chInitialState = -1;
|
||||
long prevTs = -1, initialTs = 0;
|
||||
for (CompositeEvent event : events) {
|
||||
int chState = getChannelState(ch, event);
|
||||
long ts = event.getTimestamp();
|
||||
|
||||
if (chPrevState == -1) {
|
||||
chPrevState = chState;
|
||||
}
|
||||
if (prevTs == -1) {
|
||||
prevTs = ts;
|
||||
}
|
||||
if (chInitialState == -1) {
|
||||
chInitialState = chState;
|
||||
initialTs = ts;
|
||||
}
|
||||
if (chState != chPrevState) {
|
||||
long delta = ts - prevTs;
|
||||
if (delta > 0x7fff) {
|
||||
useLongDeltas = true;
|
||||
}
|
||||
// encode state
|
||||
if (chState == 0)
|
||||
delta |= SIGN_FLAG;
|
||||
|
||||
chDeltas.add(delta);
|
||||
|
||||
prevTs = ts;
|
||||
chPrevState = chState;
|
||||
}
|
||||
}
|
||||
|
||||
if (useLongDeltas) {
|
||||
System.out.println("using long deltas for ch #" + ch);
|
||||
}
|
||||
|
||||
// TODO: why do we pass a timestamp as a record index?
|
||||
writeChannelData(ch, chDeltas, chPrevState, (int)prevTs, chInitialState, (int)initialTs, useLongDeltas);
|
||||
}
|
||||
|
||||
writeChannelDataFooter();
|
||||
stream.flush();
|
||||
}
|
||||
|
||||
private int getChannelState(int ch, CompositeEvent event) {
|
||||
switch (ch) {
|
||||
case 0:
|
||||
return event.isPrimaryTriggerAsInt();
|
||||
case 1:
|
||||
return event.isSecondaryTriggerAsInt();
|
||||
case 2:
|
||||
return event.isTrgAsInt();
|
||||
case 3:
|
||||
return event.isSyncAsInt();
|
||||
}
|
||||
if (ch >= 4 && ch < 4 + 6) {
|
||||
return event.isCoil(ch - 4);
|
||||
}
|
||||
if (ch >= 10 && ch < 10 + 6) {
|
||||
return event.isInjector(ch - 10);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void writeHeader() throws IOException {
|
||||
writeByte(magic);
|
||||
|
||||
stream.writeVarLength(version);
|
||||
stream.writeString(title);
|
||||
stream.flush();
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(SUB);
|
||||
stream.writeVarLength(frequency);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(reservedDurationInSamples);
|
||||
stream.writeVarLength(frequencyDivided);
|
||||
write(0, 2);
|
||||
stream.writeVarLength(numChannels);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(0);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
for (int i = 0; i < numChannels; i++) {
|
||||
writeId(i, 1);
|
||||
}
|
||||
stream.writeVarLength(0);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
|
||||
writeId(7, 7);
|
||||
stream.writeVarLength(SUB);
|
||||
stream.writeVarLength(0);
|
||||
}
|
||||
|
||||
private void writeChannelHeader(int ch) throws IOException {
|
||||
stream.writeVarLength(0xff);
|
||||
stream.writeVarLength(ch);
|
||||
stream.writeString(channelNames[ch]);
|
||||
write(0, 2);
|
||||
stream.writeDouble(1.0);
|
||||
|
||||
stream.writeVarLength(0);
|
||||
|
||||
stream.writeDouble(0.0);
|
||||
stream.writeVarLength(1); // or 2
|
||||
stream.writeDouble(0.0); // or 1.0
|
||||
|
||||
// this part sounds like the 'next' pointer?
|
||||
if (ch == numChannels - 1) {
|
||||
stream.writeVarLength(0);
|
||||
} else {
|
||||
writeId(1 + ch, 1);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
stream.writeVarLength((CHANNEL_FLAGS[ch & 7] >> (i * 8)) & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeChannelDataHeader() throws IOException {
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(scaledDurationInSamples);
|
||||
stream.writeVarLength(0);
|
||||
write(0, 4);
|
||||
stream.writeVarLength(numChannels);
|
||||
write(0, 3);
|
||||
writeId(0, 1);
|
||||
stream.writeVarLength(0);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
write(0, 3);
|
||||
|
||||
for (int i = 0; i < numChannels; i++) {
|
||||
writeChannelHeader(i);
|
||||
}
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
write(new int[]{ SUB, SUB, 0, SUB, 0, SUB });
|
||||
write(0, 6);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
write(0, 2);
|
||||
stream.writeVarLength(reservedDurationInSamples);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(SUB);
|
||||
stream.writeVarLength(reservedDurationInSamples);
|
||||
stream.writeVarLength(frequencyDivided);
|
||||
write(0, 2);
|
||||
stream.writeVarLength(SUB);
|
||||
write(0, 2);
|
||||
stream.writeVarLength(1);
|
||||
write(0, 3);
|
||||
//writeId(0, 0);
|
||||
writeId(7, 0);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
write(new int[]{ (int)realDurationInSamples, (int)realDurationInSamples, (int)realDurationInSamples });
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(SUB);
|
||||
stream.writeVarLength(0);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(0);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
write(SUB, 4);
|
||||
stream.writeVarLength(0);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(frequency);
|
||||
write(0, 3);
|
||||
stream.writeVarLength(1);
|
||||
write(0, 3);
|
||||
writeId(0, 0);
|
||||
write(new int[]{ 0, 1, 1, 0, 1, 0x13 });
|
||||
stream.writeVarLength(SUB);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(realDurationInSamples);
|
||||
write(0, 2);
|
||||
stream.writeVarLength(numChannels);
|
||||
write(new int[]{ 1, 0, 1 });
|
||||
}
|
||||
|
||||
private void writeChannelData(int ch, List<Long> chDeltas, int chLastState, int lastRecord, int chInitialState, int initialRecord, boolean useLongDeltas) throws IOException {
|
||||
int numEdges = chDeltas.size();
|
||||
if (numEdges == 0) {
|
||||
initialRecord = 0;
|
||||
lastRecord = 0;
|
||||
}
|
||||
stream.writeVarLength(CHANNEL_BLOCK);
|
||||
// channel#0 is somehow special...
|
||||
if (ch == 0) {
|
||||
stream.writeVarLength(SUB);
|
||||
stream.writeVarLength(BLOCK);
|
||||
}
|
||||
|
||||
stream.writeVarLength(ch + 1);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(realDurationInSamples);
|
||||
stream.writeVarLength(1);
|
||||
stream.writeVarLength(lastRecord);
|
||||
|
||||
// todo: why do we convert from
|
||||
int numSamplesLeft = (int)(realDurationInSamples - lastRecord);
|
||||
stream.writeVarLength(numSamplesLeft);
|
||||
|
||||
stream.writeVarLength(chLastState);
|
||||
|
||||
int chFlag = (numEdges == 0) ? FLAG_EMPTY : (useLongDeltas ? FLAG_NOTEMPTY_LONG : FLAG_NOTEMPTY);
|
||||
stream.writeVarLength(chFlag);
|
||||
|
||||
if (ch == 0) {
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(BLOCK);
|
||||
write(0, 11);
|
||||
if (useLongDeltas) {
|
||||
stream.writeVarLength(BLOCK);
|
||||
write(0, 6);
|
||||
}
|
||||
stream.writeVarLength(BLOCK);
|
||||
} else {
|
||||
write(0, 10);
|
||||
if (useLongDeltas) {
|
||||
write(0, 5);
|
||||
}
|
||||
}
|
||||
|
||||
stream.writeVarLength(numEdges);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(numEdges);
|
||||
// this fixes "32k records limit"
|
||||
stream.writeVarLength(numEdges >> 15);
|
||||
stream.writeVarLength(numEdges & 0x7fff);
|
||||
|
||||
writeEdges(chDeltas, useLongDeltas);
|
||||
|
||||
if (ch == 0) {
|
||||
stream.writeVarLength(BLOCK);
|
||||
write(0, 6);
|
||||
if (!useLongDeltas) {
|
||||
stream.writeVarLength(BLOCK);
|
||||
write(0, 6);
|
||||
}
|
||||
stream.writeVarLength(BLOCK);
|
||||
} else {
|
||||
write(0, 4);
|
||||
if (!useLongDeltas) {
|
||||
write(0, 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (numEdges == 0) {
|
||||
write(0, 5);
|
||||
return;
|
||||
}
|
||||
|
||||
int numRecords = 1;
|
||||
stream.writeVarLength(numRecords);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(numRecords);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(numRecords);
|
||||
writeRecord(0, 0, -1, chFlag);
|
||||
}
|
||||
|
||||
private void writeEdges(List<Long> chDeltas, boolean useLongDeltas) throws IOException {
|
||||
for (long d : chDeltas) {
|
||||
// set 16-bit 'sign' flag
|
||||
if (!useLongDeltas && (d & SIGN_FLAG) == SIGN_FLAG)
|
||||
d = (d & 0x7fff) | (SIGN_FLAG >> 16);
|
||||
writeByte((byte)(d & 0xff));
|
||||
writeByte((byte)((d >> 8) & 0xff));
|
||||
if (useLongDeltas) {
|
||||
writeByte((byte)((d >> 16) & 0xff));
|
||||
writeByte((byte)((d >> 24) & 0xff));
|
||||
}
|
||||
}
|
||||
writeByte(0x00);
|
||||
}
|
||||
|
||||
private void writeByte(int i) throws IOException {
|
||||
stream.writeByte(i);
|
||||
}
|
||||
|
||||
private void writeWord(int d) throws IOException {
|
||||
writeByte((byte)(d & 0xff));
|
||||
writeByte((byte)((d >> 8) & 0xff));
|
||||
}
|
||||
private void writeQword(long l) throws IOException {
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
writeByte((byte)(l & 0xFF));
|
||||
l >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeRecord(long record, long idx, long prevIdx, long type) throws IOException {
|
||||
writeQword(record);
|
||||
writeQword(idx);
|
||||
writeQword(prevIdx);
|
||||
writeQword(type);
|
||||
}
|
||||
|
||||
private void writeChannelDataFooter() throws IOException {
|
||||
write(0, 3);
|
||||
stream.writeVarLength(1);
|
||||
stream.writeVarLength(1);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(numChannels);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeFooter() throws IOException {
|
||||
if (stream == null)
|
||||
return;
|
||||
System.out.println("Writing " + eventsBuffer.size() + " event(s)");
|
||||
writeEvents(eventsBuffer);
|
||||
stream.writeVarLength(BLOCK);
|
||||
for (int i = 0; i < numChannels; i++) {
|
||||
writeId(i, 1);
|
||||
}
|
||||
stream.writeVarLength(1);
|
||||
writeId(numChannels, BLOCK);
|
||||
for (int i = 0; i < numChannels; i++) {
|
||||
writeId(i, 1);
|
||||
}
|
||||
stream.writeVarLength(1);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(frequency);
|
||||
write(0, 16);
|
||||
stream.writeVarLength(0x01);
|
||||
// ???
|
||||
stream.writeVarLength(0x23);
|
||||
stream.writeVarLength(SUB);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(numChannels + 1);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeVarLength(0xFFFFFFFFFFFFFFFFL);
|
||||
stream.writeVarLength(0xFFFFFFFFL);
|
||||
stream.writeVarLength(1);
|
||||
write(0, 3);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(0);
|
||||
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(0);
|
||||
stream.writeDouble(1.0);
|
||||
stream.writeVarLength(SUB);
|
||||
write(0, 6);
|
||||
stream.writeVarLength(1);
|
||||
write(0, 4);
|
||||
|
||||
stream.writeVarLength(1);
|
||||
// ???
|
||||
stream.writeVarLength(0x29);
|
||||
stream.writeVarLength(SUB);
|
||||
|
||||
writeTimingMarker();
|
||||
|
||||
stream.flush();
|
||||
System.out.println("writeFooter " + fileName);
|
||||
}
|
||||
|
||||
private void writeTimingMarker() throws IOException {
|
||||
stream.writeVarLength(BLOCK);
|
||||
stream.writeVarLength(numChannels + 2);
|
||||
write(0, 4);
|
||||
stream.writeString("Timing Marker Pair");
|
||||
stream.writeString("A1");
|
||||
stream.writeString("A2");
|
||||
write(0, 2);
|
||||
stream.writeVarLength(SUB);
|
||||
write(0, 9);
|
||||
}
|
||||
|
||||
private void writeId(int i1, int i2) throws IOException {
|
||||
stream.writeVarLength(LOGIC16);
|
||||
stream.writeVarLength(i1);
|
||||
stream.writeVarLength(i2);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void write(int value, int num) throws IOException {
|
||||
for (int i = 0; i < num; i++)
|
||||
stream.writeVarLength(value);
|
||||
}
|
||||
|
||||
private void write(int[] values) throws IOException {
|
||||
for (int value : values)
|
||||
stream.writeVarLength(value);
|
||||
}
|
||||
|
||||
private void writeRaw(int value, int num) throws IOException {
|
||||
for (int i = 0; i < num; i++) {
|
||||
writeByte(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package com.rusefi.stream;
|
||||
|
||||
import com.rusefi.composite.CompositeEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LogicdataStreamFileCsvSandbox {
|
||||
|
||||
// 1 second
|
||||
private static final int maxDelayTime = 1_000_000;
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length == 0)
|
||||
throw new IllegalArgumentException("I want file name parameter please");
|
||||
|
||||
String filename = args[0];
|
||||
List<CompositeEvent> events = readCsvFile(filename);
|
||||
|
||||
|
||||
LogicdataStreamFile file = new LogicdataStreamFile(args[1]);
|
||||
file.append(events);
|
||||
file.close();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<CompositeEvent> readCsvFile(String filename) {
|
||||
List<CompositeEvent> events = new ArrayList<>();
|
||||
|
||||
try {
|
||||
System.out.println("Reading " + filename);
|
||||
BufferedReader reader = new BufferedReader(new FileReader(filename));
|
||||
// skip header
|
||||
reader.readLine();
|
||||
reader.readLine();
|
||||
reader.readLine();
|
||||
// read records
|
||||
String line;
|
||||
int cur_time = 0;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
//System.out.println("* " + line);
|
||||
String[] tokens = line.split(",");
|
||||
int v1 = Integer.parseInt(tokens[0]);
|
||||
int v2 = Integer.parseInt(tokens[1]);
|
||||
int v3 = Integer.parseInt(tokens[2]);
|
||||
int v4 = Integer.parseInt(tokens[3]);
|
||||
int time = (int) (Double.parseDouble(tokens[4]) * 1000.0);
|
||||
int dt = (int) (Double.parseDouble(tokens[5]) * 1000.0);
|
||||
int v5 = Integer.parseInt(tokens[6]);
|
||||
int v6 = Integer.parseInt(tokens[7]);
|
||||
|
||||
// we allow time to increment only in small amounts.
|
||||
// for time discontinuities we jump 1 sec
|
||||
if (dt < 0 || dt > maxDelayTime)
|
||||
dt = maxDelayTime;
|
||||
// we want to catch integer overflow here
|
||||
cur_time = Math.addExact(cur_time, dt);
|
||||
|
||||
System.out.println("* " + cur_time);
|
||||
events.add(new CompositeEvent(cur_time, v1 == 1, v2 == 1, v3 == 1, v4 == 1, v5 == 1, v6 == 1));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
System.out.println("Found " + events.size() + " records");
|
||||
return events;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package com.rusefi.stream;
|
||||
|
||||
import com.rusefi.composite.CompositeEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LogicdataStreamFileSandbox {
|
||||
public static void main(String[] args) {
|
||||
List<CompositeEvent> events = new ArrayList<>();
|
||||
|
||||
long timestamp = 10;
|
||||
|
||||
events.add(new CompositeEvent(timestamp, false, false, false, false, false, false));
|
||||
|
||||
events.add(new CompositeEvent(20, true, false, true, false, false, false));
|
||||
events.add(new CompositeEvent(30, false, false, false, false, false, false));
|
||||
|
||||
for (int i = 0; i < 63000; i++) {
|
||||
|
||||
timestamp = 100 + i * 1000;
|
||||
|
||||
boolean primary = (i % 2) == 0;
|
||||
|
||||
events.add(new CompositeEvent(timestamp, primary, false, false, false, false, false));
|
||||
}
|
||||
|
||||
events.add(new CompositeEvent(timestamp + 1000, false, false, false, false, true, false));
|
||||
events.add(new CompositeEvent(timestamp + 2030, false, false, true, false, false, true));
|
||||
|
||||
LogicdataStreamFile file = new LogicdataStreamFile("sandbox.logicdata");
|
||||
file.append(events);
|
||||
file.close();
|
||||
}
|
||||
}
|
|
@ -7,7 +7,6 @@ import java.util.List;
|
|||
|
||||
public abstract class StreamFile {
|
||||
// todo: always write into Writer since it has better API, it's insane to have to references into same stream
|
||||
protected LogicdataOutputStream stream;
|
||||
protected Writer writer;
|
||||
|
||||
public StreamFile() {
|
||||
|
@ -35,19 +34,10 @@ public abstract class StreamFile {
|
|||
}
|
||||
writer = null;
|
||||
}
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
// ignoring this one
|
||||
}
|
||||
stream = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void createFileWriter(String fileName) throws FileNotFoundException {
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(fileName);
|
||||
stream = new LogicdataOutputStream(fileOutputStream);
|
||||
writer = new OutputStreamWriter(fileOutputStream);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
package com.rusefi.stream;
|
||||
|
||||
import com.rusefi.composite.CompositeEvent;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* https://en.wikipedia.org/wiki/Value_change_dump
|
||||
*
|
||||
* @see FileLog#WIKI_URL
|
||||
*/
|
||||
public class VcdStreamFile extends StreamFile {
|
||||
private static final String TAG_PRIMARY = "t";
|
||||
private static final String TAG_SECONDARY = "s";
|
||||
private static final String TAG_TRG = "r";
|
||||
private static final String TAG_SYNC = "y";
|
||||
private static final String TAG_COIL = "c";
|
||||
private static final String TAG_INJ = "i";
|
||||
private final String fileName;
|
||||
|
||||
public VcdStreamFile(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
private static void writeHeader(Writer writer, Date date) throws IOException {
|
||||
writer.write("$date\n");
|
||||
writer.write("\t" + date + "\n");
|
||||
writer.write("$end\n" +
|
||||
"$version\n" +
|
||||
" 1.0\n" +
|
||||
"$end\n" +
|
||||
"$timescale\n" +
|
||||
" 1ps\n" +
|
||||
"$end\n" +
|
||||
"$scope module test $end\n" +
|
||||
"$var wire 1 " + TAG_PRIMARY + " PRI_TRG $end\n" +
|
||||
"$var wire 1 " + TAG_SECONDARY + " SEC_TRG $end\n" +
|
||||
"$var wire 1 " + TAG_TRG + " TRG $end\n" +
|
||||
"$var wire 1 " + TAG_SYNC + " SYNC $end\n" +
|
||||
"$var wire 1 " + TAG_COIL + " COIL $end\n" +
|
||||
"$var wire 1 " + TAG_INJ + " INJ $end\n" +
|
||||
"$upscope $end\n" +
|
||||
"$enddefinitions $end\n" +
|
||||
"$dumpvars\n");
|
||||
}
|
||||
|
||||
public static void appendEvents(List<CompositeEvent> events, Writer writer) throws IOException {
|
||||
for (CompositeEvent event : events) {
|
||||
writer.write("#" + event.getTimestamp() + "\n");
|
||||
writer.write(event.isPrimaryTriggerAsInt() + TAG_PRIMARY + "\n");
|
||||
writer.write(event.isSecondaryTriggerAsInt() + TAG_SECONDARY + "\n");
|
||||
writer.write(event.isTrgAsInt() + TAG_TRG + "\n");
|
||||
writer.write(event.isSyncAsInt() + TAG_SYNC + "\n");
|
||||
writer.write(event.isCoil() + TAG_COIL + "\n");
|
||||
writer.write(event.isInjector() + TAG_INJ + "\n");
|
||||
}
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
public static void writeVCD(List<CompositeEvent> events, Writer writer, Date date) throws IOException {
|
||||
writeHeader(writer, date);
|
||||
appendEvents(events, writer);
|
||||
}
|
||||
|
||||
public static void writeVCD(List<CompositeEvent> events, FileWriter fileWriter) throws IOException {
|
||||
writeVCD(events, fileWriter, new Date());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(List<CompositeEvent> events) {
|
||||
try {
|
||||
if (writer == null) {
|
||||
createFileWriter(fileName);
|
||||
writeHeader(writer, new Date());
|
||||
}
|
||||
appendEvents(events, writer);
|
||||
} catch (IOException e) {
|
||||
// ignoring this one
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package com.rusefi.composite.test;
|
||||
|
||||
import com.rusefi.stream.VcdStreamFile;
|
||||
import com.rusefi.composite.CompositeEvent;
|
||||
import com.rusefi.composite.CompositeParser;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class CompositeParserTest {
|
||||
@Test
|
||||
public void testParseAndExportToVCD() throws IOException {
|
||||
byte[] input = {0, 1, 110, -101, 53, 58, 1, 110, -86, -43, 42, 1, 110, -78, 14, 10, 1, 110, -74, -67, 8, 1, 110, -23, -30, 9, 1};
|
||||
|
||||
List<CompositeEvent> events = CompositeParser.parse(input);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
//FileWriter writer = new FileWriter("rusEFI.vcd");
|
||||
VcdStreamFile.writeVCD(events, writer, new Date(1590847552574L));
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package com.rusefi.stream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class LogicdataStreamFileTest {
|
||||
@Test
|
||||
public void testWriteAs() throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
LogicdataOutputStream logicdataOutputStream = new LogicdataOutputStream(baos);
|
||||
logicdataOutputStream.writeVarLength(10);
|
||||
|
||||
byte[] bytes = baos.toByteArray();
|
||||
assertEquals(2, bytes.length);
|
||||
assertEquals(1, bytes[0]);
|
||||
assertEquals(10, bytes[1]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue