summaryrefslogtreecommitdiff
path: root/dslog/DslogReader.java
blob: 73d7dc55b8a4009060081bee1bcb609afbb9bb62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package dslog;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.lang.UnsupportedOperationException;
import java.time.Duration;
import java.time.Instant;
import java.util.stream.IntStream;

class DslogReader implements Closeable {
	private final InputStream reader;

	public final int version;
	public final Instant startTime;
	private long i = 0;

	public DslogReader(InputStream reader) throws IOException {
		this.reader = reader;
		this.version = Read.i32(reader);
		switch (this.version) {
		case 0: // ????-???? 2012
			this.startTime = Read.LVTimestamp(reader);
			break;
		case 1: // ????-???? 2014
			this.startTime = Read.LVTimestamp(reader);
			break;
		case 2: // ????-2015
			throw new UnsupportedOperationException("TODO: DSLOG v2 support");
		case 3: // 2016-now
			this.startTime = Read.LVTimestamp(reader);
			break;
		default:
			throw new UnsupportedOperationException("DSLOG file version ("+this.version+") newer than log reader (3)");
		}
	}

	public static class Entry {
		public Instant time;

		public Duration tripTime;
		public short lostPackets;
		public double voltageVolts;
		public double cpuPct;
		public boolean
			robotDisable,
			robotAuto,
			robotTele,
			dsDisable,
			dsAuto,
			dsTele,
			watchdog,
			brownout;
		public double canPct;
		public double signalDB;
		public double bandwidthMb;
		public short pdpID;
		public short pdpPad;
		public double pdpValues[];
		public short pdpResistance;
		public short pdpVoltage;
		public short pdpTemperature;
	}

	/**
	 * @see https://www.chiefdelphi.com/forums/showthread.php?t=104689
	 */
	public Entry readEntry() throws IOException{
		switch (version) {
		case 0:
			return new Entry() {{
				time = startTime.plusMillis(20*i++);

				/*  0  = 0 */
				/*  0+4= 4 */tripTime = Duration.ofNanos((long)(Read.f32(reader)*1000));
				/*  4+4= 8 */voltageVolts = Read.f32(reader);
				/*  8+4=12 */cpuPct = Read.f32(reader);
				/* 12+1=13 */short bits = Read.u8(reader);
				robotDisable = (bits & (1<<2)) == 0;
				robotAuto    = (bits & (1<<3)) == 0;
				robotTele    = (bits & (1<<4)) == 0;
				dsDisable    = (bits & (1<<5)) == 0;
				dsAuto       = (bits & (1<<6)) == 0;
				dsTele       = (bits & (1<<7)) == 0;
				/* 13+1=14 */lostPackets = Read.i8(reader);
			}};
		case 1:
			return new Entry() {{
				time = startTime.plusMillis(20*i++);

				time = startTime.plusMillis(20*i++);

				/*  0  = 0 */
				/*  0+4= 4 */tripTime = Duration.ofNanos((long)(Read.f32(reader)*1000));
				/*  4+4= 8 */voltageVolts = Read.f32(reader);
				/*  8+4=12 */cpuPct = Read.f32(reader);
				/* 12+1=13 */short bits = Read.u8(reader);
				robotDisable = (bits & (1<<0)) == 0;
				robotAuto    = (bits & (1<<1)) == 0;
				robotTele    = (bits & (1<<2)) == 0;
				dsDisable    = (bits & (1<<3)) == 0;
				dsAuto       = (bits & (1<<4)) == 0;
				dsTele       = (bits & (1<<5)) == 0;
				/* 13+1=14 */lostPackets = Read.i8(reader);
			}};
		case 2:
			throw new UnsupportedOperationException("TODO: DSLOG v2 support");
		case 3:
			return new Entry() {{
				time = startTime.plusMillis(20*i++);
				// Read the 35-byte structure

				// Read the 10 bytes of non-PDP data

				/* 0  = 0 */
				/* 0+1= 1 */tripTime = Duration.ofNanos((long)(Util.unpack(Read.u8(reader), 7,1)*1_000_000));
				/* 1+1= 2 */lostPackets = Read.u8(reader);
				/* 2+2= 4 */voltageVolts = Util.unpack(Read.u16(reader), 8,8);
				/* 5+1= 5 */cpuPct = Util.unpack(Read.u8(reader), 7,1);
				/* 5+1= 6 */short bits = Read.u8(reader);
				robotDisable = (bits & (1<<0)) == 0;
				robotAuto    = (bits & (1<<1)) == 0;
				robotTele    = (bits & (1<<2)) == 0;
				dsDisable    = (bits & (1<<3)) == 0;
				dsAuto       = (bits & (1<<4)) == 0;
				dsTele       = (bits & (1<<5)) == 0;
				watchdog     = (bits & (1<<6)) == 0;
				brownout     = (bits & (1<<7)) == 0;
				/* 6+1= 7 */canPct = Util.unpack(Read.u8(reader), 7,1);
				/* 7+1= 8 */signalDB = Util.unpack(Read.u8(reader), 7,1);
				/* 8+2=10 */bandwidthMb = Util.unpack(Read.u16(reader), 8,8);

				// Read the 25 bytes of PDP data
				
				/*  0  = 0 */
				/*  0+1= 1 */pdpPad = Read.u8(reader);
				/*  1+1= 2 */pdpID = Read.u8(reader);
				pdpValues = IntStream.of(Util.reverse(Util.concat(
				/*  2+5= 7 */   Read.u10x4(reader),
				/*  7+5=12 */   Read.u10x4(reader),
				/* 12+5=17 */   Read.u10x4(reader),
				/* 17+5=22 */   Read.u10x4(reader))))
					.mapToDouble(i -> Util.unpack((short)i, 7,3))
					.toArray();
				/* 22+1=23 */pdpResistance = Read.u8(reader);
				/* 23+1=24 */pdpVoltage = Read.u8(reader);
				/* 24+1=25 */pdpTemperature = Read.u8(reader);
			}};
		default:
			throw new UnsupportedOperationException("DSLOG file version newer than log reader");
		}
	}

	public void close() throws IOException {
		reader.close();
	}
}