-
Notifications
You must be signed in to change notification settings - Fork 0
/
telemetry.go
144 lines (123 loc) · 2.84 KB
/
telemetry.go
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
package telemetry
import (
"bytes"
"encoding/binary"
"encoding/gob"
"encoding/json"
"fmt"
"time"
"unsafe"
)
// same definition and order as common.h in jd3nn1s/nerdobd2
type Header struct {
Type uint8
}
const (
TypeTelemetry = 1
TypeTiming = 2
)
type Telemetry struct {
RPM float32
OilPressure float32
Speed float32
FuelRemaining float32
FuelLevel uint8
OilTemp float32
CoolantTemp float32
AirIntakeTemp float32
BatteryVoltage float32
Latitude float64
Longitude float64
Altitude float32
Track float32
GPSSpeed float32
GasPedalAngle uint8
}
type TelemetryWithStatus struct {
*Telemetry
WarningFields []string `json:",omitempty"`
ErrorFields []string `json:",omitempty"`
}
type Timing struct {
BestLap JSONDuration
BestLapDriver string
LastLap JSONDuration
LapCount int
DriverName string
TeamAheadName string
TeamAheadLapCount int
TeamAheadLastLap JSONDuration
TeamAheadSplit JSONDuration
}
func (t Telemetry) Encode() ([]byte, error) {
buf := new(bytes.Buffer)
err := binary.Write(buf, binary.LittleEndian, Header{TypeTelemetry})
if err != nil {
return buf.Bytes(), err
}
err = binary.Write(buf, binary.LittleEndian, t)
return buf.Bytes(), err
}
func (t Timing) Encode() ([]byte, error) {
buf := new(bytes.Buffer)
err := binary.Write(buf, binary.LittleEndian, Header{TypeTiming})
if err != nil {
return buf.Bytes(), err
}
enc := gob.NewEncoder(buf)
err = enc.Encode(t)
return buf.Bytes(), err
}
func Decode(data []byte) (interface{}, error) {
var header Header
reader := bytes.NewReader([]byte(data))
err := binary.Read(reader, binary.LittleEndian, &header)
if err != nil {
return nil, err
}
if header.Type == TypeTelemetry {
var tempTelemetry Telemetry
err := binary.Read(reader, binary.LittleEndian, &tempTelemetry)
return tempTelemetry, err
} else if header.Type == TypeTiming {
var tempTiming Timing
dec := gob.NewDecoder(reader)
err := dec.Decode(&tempTiming)
return tempTiming, err
} else {
return nil, fmt.Errorf("Unknown message type (%d)", header.Type)
}
}
// Timing telemetry
type JSONDuration time.Duration
func (d JSONDuration) MarshalJSON() ([]byte, error) {
minutes := int(time.Duration(d).Minutes())
seconds := (time.Duration(d) - (time.Duration(minutes) * time.Minute)).Seconds()
stamp := fmt.Sprintf("\"%02d:%05.2f\"", minutes, seconds)
return []byte(stamp), nil
}
func (t Timing) JSONEncode() ([]byte, error) {
data := struct {
Type string
Data Timing
}{
"timing",
t,
}
return json.Marshal(data)
}
func (t TelemetryWithStatus) JSONEncode() ([]byte, error) {
data := struct {
Type string
Data TelemetryWithStatus
}{
"telemetry",
t,
}
return json.Marshal(data)
}
func MaxTelemetrySize() int {
var hdr Header
var t Telemetry
return int(unsafe.Sizeof(hdr) + unsafe.Sizeof(t))
}