Satisfactory fuel calculator done (still have plenty to do on it)
This commit is contained in:
+325
-277
@@ -1,29 +1,5 @@
|
||||
Windows:
|
||||
1:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 359
|
||||
Y0: 355
|
||||
Width: 120
|
||||
Height: 49
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: YELLOW
|
||||
Title: RPMColour
|
||||
uidata:
|
||||
WID: 1
|
||||
TelemetryField: RPM State Colour
|
||||
2:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 74
|
||||
@@ -45,177 +21,9 @@ Windows:
|
||||
PreviewValue: "12"
|
||||
Title: TC
|
||||
uidata:
|
||||
WID: 2
|
||||
WID: 1
|
||||
TelemetryField: TC Control
|
||||
3:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 60
|
||||
Y0: 91
|
||||
Width: 85
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "123"
|
||||
Title: Lap
|
||||
uidata:
|
||||
WID: 3
|
||||
TelemetryField: Lap Number
|
||||
4:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 9
|
||||
Y0: 413
|
||||
Width: 57
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "12"
|
||||
Title: ABS
|
||||
uidata:
|
||||
WID: 4
|
||||
TelemetryField: ABS Control
|
||||
5:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 694
|
||||
Y0: 367
|
||||
Width: 100
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "101.4"
|
||||
Title: Oil T
|
||||
uidata:
|
||||
WID: 5
|
||||
TelemetryField: Oil Temperature
|
||||
6:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 60
|
||||
Y0: 155
|
||||
Width: 226
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "06:45.123"
|
||||
Title: Last Lap
|
||||
uidata:
|
||||
WID: 6
|
||||
TelemetryField: Last Lap Time
|
||||
7:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 590
|
||||
Y0: 367
|
||||
Width: 100
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "101.5"
|
||||
Title: Water T
|
||||
uidata:
|
||||
WID: 7
|
||||
TelemetryField: Water Temperature
|
||||
8:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 642
|
||||
Y0: 188
|
||||
Width: 150
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "2.7"
|
||||
Title: Fuel Cur Lap
|
||||
uidata:
|
||||
WID: 8
|
||||
TelemetryField: Fuel Current Lap
|
||||
9:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 470
|
||||
Y0: 188
|
||||
Width: 168
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: 12.3 L
|
||||
Title: Fuel Last Lap
|
||||
uidata:
|
||||
WID: 9
|
||||
TelemetryField: Fuel Last Lap
|
||||
10:
|
||||
2:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 354
|
||||
@@ -237,33 +45,9 @@ Windows:
|
||||
PreviewValue: R
|
||||
Title: Box
|
||||
uidata:
|
||||
WID: 10
|
||||
WID: 2
|
||||
TelemetryField: Gear
|
||||
11:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 142
|
||||
Y0: 19
|
||||
Width: 500
|
||||
Height: 20
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 1
|
||||
TextSize: 2
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 1
|
||||
PreviewValue: "5678"
|
||||
Title: TACHO
|
||||
uidata:
|
||||
WID: 11
|
||||
TelemetryField: RPM
|
||||
12:
|
||||
3:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 140
|
||||
@@ -285,9 +69,105 @@ Windows:
|
||||
PreviewValue: "6"
|
||||
Title: Thr
|
||||
uidata:
|
||||
WID: 12
|
||||
WID: 3
|
||||
TelemetryField: Throttle Control
|
||||
13:
|
||||
4:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 359
|
||||
Y0: 355
|
||||
Width: 120
|
||||
Height: 49
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: YELLOW
|
||||
Title: RPMColour
|
||||
uidata:
|
||||
WID: 4
|
||||
TelemetryField: RPM State Colour
|
||||
5:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 60
|
||||
Y0: 155
|
||||
Width: 226
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "06:45.123"
|
||||
Title: Last Lap
|
||||
uidata:
|
||||
WID: 5
|
||||
TelemetryField: Last Lap Time
|
||||
6:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 470
|
||||
Y0: 188
|
||||
Width: 168
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: 12.3 L
|
||||
Title: Fuel Last Lap
|
||||
uidata:
|
||||
WID: 6
|
||||
TelemetryField: Fuel Last Lap
|
||||
7:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 142
|
||||
Y0: 19
|
||||
Width: 500
|
||||
Height: 20
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 1
|
||||
TextSize: 2
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 1
|
||||
PreviewValue: "5678"
|
||||
Title: TACHO
|
||||
uidata:
|
||||
WID: 7
|
||||
TelemetryField: RPM
|
||||
8:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 694
|
||||
@@ -309,57 +189,9 @@ Windows:
|
||||
PreviewValue: "4.56"
|
||||
Title: Oil P
|
||||
uidata:
|
||||
WID: 13
|
||||
WID: 8
|
||||
TelemetryField: Oil Pressure
|
||||
14:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 436
|
||||
Y0: 71
|
||||
Width: 206
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "9999"
|
||||
Title: Dig Tacho
|
||||
uidata:
|
||||
WID: 14
|
||||
TelemetryField: RPM
|
||||
15:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 710
|
||||
Y0: 8
|
||||
Width: 84
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: PIT
|
||||
Title: Pit Sp
|
||||
uidata:
|
||||
WID: 15
|
||||
TelemetryField: Pit Speed Limiter
|
||||
16:
|
||||
9:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 331
|
||||
@@ -381,9 +213,129 @@ Windows:
|
||||
PreviewValue: "234"
|
||||
Title: SPEEDO
|
||||
uidata:
|
||||
WID: 16
|
||||
WID: 9
|
||||
TelemetryField: Speed
|
||||
17:
|
||||
10:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 694
|
||||
Y0: 367
|
||||
Width: 100
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "101.4"
|
||||
Title: Oil T
|
||||
uidata:
|
||||
WID: 10
|
||||
TelemetryField: Oil Temperature
|
||||
11:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 590
|
||||
Y0: 367
|
||||
Width: 100
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "101.5"
|
||||
Title: Water T
|
||||
uidata:
|
||||
WID: 11
|
||||
TelemetryField: Water Temperature
|
||||
12:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 642
|
||||
Y0: 188
|
||||
Width: 150
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "2.7"
|
||||
Title: Fuel Cur Lap
|
||||
uidata:
|
||||
WID: 12
|
||||
TelemetryField: Fuel Current Lap
|
||||
13:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 436
|
||||
Y0: 71
|
||||
Width: 206
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "9999"
|
||||
Title: Dig Tacho
|
||||
uidata:
|
||||
WID: 13
|
||||
TelemetryField: RPM
|
||||
14:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 710
|
||||
Y0: 8
|
||||
Width: 84
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: PIT
|
||||
Title: Pit Sp
|
||||
uidata:
|
||||
WID: 14
|
||||
TelemetryField: Pit Speed Limiter
|
||||
15:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 207
|
||||
@@ -405,9 +357,9 @@ Windows:
|
||||
PreviewValue: "61.4"
|
||||
Title: BBias
|
||||
uidata:
|
||||
WID: 17
|
||||
WID: 15
|
||||
TelemetryField: BrakeBias
|
||||
18:
|
||||
16:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 470
|
||||
@@ -429,5 +381,101 @@ Windows:
|
||||
PreviewValue: "123.4"
|
||||
Title: Fuel Level
|
||||
uidata:
|
||||
WID: 18
|
||||
WID: 16
|
||||
TelemetryField: Fuel Level
|
||||
17:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 60
|
||||
Y0: 91
|
||||
Width: 85
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "123"
|
||||
Title: Lap
|
||||
uidata:
|
||||
WID: 17
|
||||
TelemetryField: Lap Number
|
||||
18:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 9
|
||||
Y0: 413
|
||||
Width: 57
|
||||
Height: 57
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "12"
|
||||
Title: ABS
|
||||
uidata:
|
||||
WID: 18
|
||||
TelemetryField: ABS Control
|
||||
19:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 643
|
||||
Y0: 132
|
||||
Width: 149
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "10.54"
|
||||
Title: Fuel Av.
|
||||
uidata:
|
||||
WID: 19
|
||||
TelemetryField: Fuel Average Usage
|
||||
20:
|
||||
uiwindow:
|
||||
Dims:
|
||||
X0: 470
|
||||
Y0: 242
|
||||
Width: 322
|
||||
Height: 50
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 3
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 2
|
||||
PreviewValue: "41.2"
|
||||
Title: Fuel Rem.
|
||||
uidata:
|
||||
WID: 20
|
||||
TelemetryField: Fuel Expected Laps
|
||||
|
||||
@@ -171,7 +171,7 @@ func (i *IRacing) Subscribe(requestFields map[int16]telem.FieldID) {
|
||||
switch id {
|
||||
case telem.RPMStateColour:
|
||||
i.data.VirtualBinds = append(i.data.VirtualBinds, telem.NewRPMLights())
|
||||
case telem.FuelCurrentLap:
|
||||
case telem.FCCurrentLap:
|
||||
i.data.VirtualBinds = append(i.data.VirtualBinds,
|
||||
telem.NewFuelCalculator(i.logger.WithGroup("FUEL CALC")))
|
||||
default:
|
||||
|
||||
+8
-4
@@ -172,8 +172,10 @@ const (
|
||||
// RPM Dash Lights
|
||||
RPMStateColour
|
||||
// Fuel Calculator
|
||||
FuelCurrentLap
|
||||
FuelLastLap
|
||||
FCCurrentLap
|
||||
FCLastLap
|
||||
FCAverage
|
||||
FCExpectedLaps
|
||||
MaxFields
|
||||
)
|
||||
const FirstField = Speed
|
||||
@@ -217,8 +219,10 @@ var FieldNames = [MaxFields]string{
|
||||
// RPM Dash Lights
|
||||
RPMStateColour: "RPM State Colour",
|
||||
// Fuel Calculator
|
||||
FuelCurrentLap: "Fuel Current Lap",
|
||||
FuelLastLap: "Fuel Last Lap",
|
||||
FCCurrentLap: "Fuel Current Lap",
|
||||
FCLastLap: "Fuel Last Lap",
|
||||
FCAverage: "Fuel Average Usage",
|
||||
FCExpectedLaps: "Fuel Expected Laps",
|
||||
Empty: "Emtpy",
|
||||
}
|
||||
|
||||
|
||||
+168
-79
@@ -10,18 +10,47 @@ import (
|
||||
// NOTE: for managing fuel consumption and predictions we need to filter out
|
||||
// abnormal laps like going into the pits and refueling and whatnot
|
||||
|
||||
// NOTE: create a log file specifically for this, I reckon it would be better
|
||||
|
||||
type fuelCalcState int
|
||||
|
||||
const (
|
||||
MaxLaps = 256
|
||||
)
|
||||
|
||||
const (
|
||||
// leaves pits or whenever this starts
|
||||
outlap fuelCalcState = iota
|
||||
OutlapState fuelCalcState = iota
|
||||
// we cross the line for the first time, we can count real time usage here
|
||||
// but don't have history yet
|
||||
firstLap
|
||||
FirstLapState
|
||||
// We already have history and can therefore do averages
|
||||
normal
|
||||
NormalState
|
||||
)
|
||||
|
||||
type lapFuelData struct {
|
||||
Lap int // Number of the lap of this data
|
||||
StartFuelLevel float64 // Fuel level at the start/finish line
|
||||
FuelUsage float64 // Fuel used during the lap
|
||||
Valid bool // If we should consider this data for calculations
|
||||
}
|
||||
|
||||
func (lfd *lapFuelData) SetLap(lap int) {
|
||||
lfd.Lap = lap
|
||||
}
|
||||
|
||||
func (lfd *lapFuelData) SetStartFuelLevel(fuelLevel float64) {
|
||||
lfd.StartFuelLevel = fuelLevel
|
||||
}
|
||||
|
||||
func (lfd *lapFuelData) InvalidateLap() {
|
||||
lfd.Valid = false
|
||||
}
|
||||
|
||||
func (lfd *lapFuelData) CalculateFuelUsage(fuelLevel float64) {
|
||||
lfd.FuelUsage = lfd.StartFuelLevel - fuelLevel
|
||||
}
|
||||
|
||||
// FuelCalculator acts as a Virtual Field middleware
|
||||
type FuelCalculator struct {
|
||||
Logger *slog.Logger
|
||||
@@ -47,121 +76,181 @@ type FuelCalculator struct {
|
||||
maxUsage float64
|
||||
|
||||
state fuelCalcState
|
||||
|
||||
Laps [MaxLaps]lapFuelData
|
||||
CurrentLap int
|
||||
|
||||
averageFuelUsage float64
|
||||
expectedLaps float64
|
||||
}
|
||||
|
||||
func NewFuelCalculator(logger *slog.Logger) *FuelCalculator {
|
||||
return &FuelCalculator{
|
||||
Logger: logger,
|
||||
setup: &sync.Once{},
|
||||
lapHistory: make([]float64, 0, 5), // Pre-allocate space for 5 laps
|
||||
maxHistoryLaps: 3, // We want a 3-lap rolling average
|
||||
lastLapNumber: 0,
|
||||
state: outlap,
|
||||
Logger: logger,
|
||||
setup: &sync.Once{},
|
||||
lapHistory: make([]float64, 0, 5), // Pre-allocate space for 5 laps
|
||||
maxHistoryLaps: 3, // We want a 3-lap rolling average
|
||||
lastLapNumber: 0,
|
||||
state: OutlapState,
|
||||
CurrentLap: 0,
|
||||
averageFuelUsage: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) transitionState(state fuelCalcState) {
|
||||
fc.state = state
|
||||
func (fc *FuelCalculator) initializeFCTelemetryFields(td *TelemetryData) {
|
||||
td.Values[FCLastLap].Type = DataTypeSTRING
|
||||
td.Values[FCLastLap].Str = "No Data"
|
||||
|
||||
td.Values[FCCurrentLap].Type = DataTypeSTRING
|
||||
td.Values[FCCurrentLap].Str = "No Data"
|
||||
|
||||
td.Values[FCExpectedLaps].Type = DataTypeSTRING
|
||||
td.Values[FCExpectedLaps].Str = "No Data"
|
||||
|
||||
td.Values[FCAverage].Type = DataTypeSTRING
|
||||
td.Values[FCAverage].Str = "No Data"
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) crossedStartFinishLine(lap int) bool {
|
||||
return lap > fc.lastLapNumber
|
||||
func (fc *FuelCalculator) newLapData(lap int, fuelLevel float64) {
|
||||
fc.Laps[fc.CurrentLap].SetStartFuelLevel(fuelLevel)
|
||||
fc.Laps[fc.CurrentLap].SetLap(lap)
|
||||
fc.Laps[fc.CurrentLap].Valid = true
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) refueled(currentFuelLevel float64) bool {
|
||||
return currentFuelLevel > fc.fuelAtLapStart
|
||||
func (fc *FuelCalculator) MaxLapsReached(td *TelemetryData) {
|
||||
td.Values[FCLastLap].Str = "MAX!!!"
|
||||
td.Values[FCCurrentLap].Str = "MAX!!!"
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) storeStartFinishLineFuelLevels(curFuel float64, lap int) {
|
||||
fc.fuelAtLapStart = curFuel
|
||||
fc.lastLapNumber = lap
|
||||
func (fc *FuelCalculator) updateLapFuelUsage(td *TelemetryData, fuel float64) {
|
||||
fc.Logger.Debug(fmt.Sprintf("= %-2d =============================================", fc.CurrentLap))
|
||||
fc.Logger.Debug(fmt.Sprintf("-> Updating Lap Fuel Usage"))
|
||||
fc.Logger.Debug(fmt.Sprintf(" %+v", fc.Laps[fc.CurrentLap]))
|
||||
fc.Logger.Debug(fmt.Sprintf(" %f - %f = %f",
|
||||
fc.Laps[fc.CurrentLap].StartFuelLevel, fuel, fc.Laps[fc.CurrentLap].StartFuelLevel-fuel))
|
||||
|
||||
fc.Laps[fc.CurrentLap].CalculateFuelUsage(fuel)
|
||||
td.Values[FCLastLap].Str = fmt.Sprintf("%.1f", fc.Laps[fc.CurrentLap].FuelUsage)
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) calculateCurLapFuelUsage(td *TelemetryData, fuel float64) {
|
||||
td.Values[FuelCurrentLap].Type = DataTypeSTRING
|
||||
td.Values[FuelCurrentLap].Str = fmt.Sprintf("%.2f", fc.fuelAtLapStart-fuel)
|
||||
func (fc *FuelCalculator) updateAverageFuelUsage(td *TelemetryData) {
|
||||
// NOTE: this is a dumb approach on how to calculte fuel usage
|
||||
// sum := 0.0
|
||||
// lapCount := 0
|
||||
// for k := 0; k < fc.CurrentLap; k++ {
|
||||
// if !fc.Laps[k].Valid {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// sum += fc.Laps[k].FuelUsage
|
||||
// lapCount += 1
|
||||
// }
|
||||
//
|
||||
// if lapCount == 0 {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// fc.averageFuelUsage = sum / float64(lapCount)
|
||||
fc.averageFuelUsage = fc.Laps[fc.CurrentLap].FuelUsage
|
||||
|
||||
td.Values[FCAverage].Str = fmt.Sprintf("%.2f", fc.averageFuelUsage)
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) processOutlap(td *TelemetryData, lap int) {
|
||||
currentFuelLevel, err := strconv.ParseFloat(td.Values[FuelLevel].Str, 64)
|
||||
if err != nil {
|
||||
fc.Logger.Debug(fmt.Sprintf("error parsing fuel level: %+v", err))
|
||||
func (fc *FuelCalculator) updateExpectedLaps(td *TelemetryData, fuel float64) {
|
||||
fc.expectedLaps = fuel / fc.averageFuelUsage
|
||||
|
||||
td.Values[FCExpectedLaps].Str = fmt.Sprintf("%.1f", fc.expectedLaps)
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) startFinishLineCrossed(td *TelemetryData, lap int, fuel float64) {
|
||||
if fc.state == OutlapState {
|
||||
fc.state = FirstLapState
|
||||
}
|
||||
|
||||
if fc.state == FirstLapState {
|
||||
fc.state = NormalState
|
||||
}
|
||||
|
||||
// if fc.state == NormalState {
|
||||
// // In the normal state we have normal calculations to compute
|
||||
// fc.updateLapFuelUsage(td, fuel)
|
||||
// }
|
||||
|
||||
if fc.CurrentLap == MaxLaps {
|
||||
fc.MaxLapsReached(td)
|
||||
return
|
||||
}
|
||||
|
||||
if fc.crossedStartFinishLine(lap) {
|
||||
fc.storeStartFinishLineFuelLevels(currentFuelLevel, lap)
|
||||
fc.transitionState(firstLap)
|
||||
}
|
||||
// 1. Update last lap (we are still on the curret index) lap's fuel usage
|
||||
fc.updateLapFuelUsage(td, fuel)
|
||||
// 2. Update the average usage
|
||||
fc.updateAverageFuelUsage(td)
|
||||
// 3. Update the expected laps
|
||||
fc.updateExpectedLaps(td, fuel)
|
||||
|
||||
if fc.refueled(currentFuelLevel) {
|
||||
fc.transitionState(outlap)
|
||||
}
|
||||
// Go into the next lap
|
||||
fc.CurrentLap += 1
|
||||
fc.newLapData(lap, fuel)
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) processFirstlap(td *TelemetryData, lap int) {
|
||||
currentFuelLevel, err := strconv.ParseFloat(td.Values[FuelLevel].Str, 64)
|
||||
if err != nil {
|
||||
fc.Logger.Debug(fmt.Sprintf("error parsing fuel level: %+v", err))
|
||||
return
|
||||
}
|
||||
func (fc *FuelCalculator) updateCurrentLapFuelUsage(td *TelemetryData, fuel float64) {
|
||||
// NOTE: find a more performant way of float64 -> string
|
||||
fuelDelta := fc.Laps[fc.CurrentLap].StartFuelLevel - fuel
|
||||
|
||||
if fc.crossedStartFinishLine(lap) {
|
||||
fc.storeStartFinishLineFuelLevels(currentFuelLevel, lap)
|
||||
fc.transitionState(normal)
|
||||
}
|
||||
|
||||
if fc.refueled(currentFuelLevel) {
|
||||
fc.transitionState(outlap)
|
||||
}
|
||||
|
||||
fc.calculateCurLapFuelUsage(td, currentFuelLevel)
|
||||
td.Values[FCCurrentLap].Str = fmt.Sprintf("%.1f", fuelDelta)
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) processNormal(td *TelemetryData, lap int) {
|
||||
currentFuelLevel, err := strconv.ParseFloat(td.Values[FuelLevel].Str, 64)
|
||||
if err != nil {
|
||||
fc.Logger.Debug(fmt.Sprintf("error parsing fuel level: %+v", err))
|
||||
return
|
||||
}
|
||||
func (fc *FuelCalculator) updateRealTimeVariables(td *TelemetryData, lap int, fuel float64) {
|
||||
// if fc.state == OutlapState {
|
||||
// Nothing to calculate here currently
|
||||
// return
|
||||
// }
|
||||
|
||||
if fc.crossedStartFinishLine(lap) {
|
||||
fc.storeStartFinishLineFuelLevels(currentFuelLevel, lap)
|
||||
fc.transitionState(normal)
|
||||
}
|
||||
// Real time updates
|
||||
fc.updateCurrentLapFuelUsage(td, fuel)
|
||||
}
|
||||
|
||||
if fc.refueled(currentFuelLevel) {
|
||||
fc.transitionState(outlap)
|
||||
}
|
||||
|
||||
fc.calculateCurLapFuelUsage(td, currentFuelLevel)
|
||||
|
||||
// And here we add how to calculate last lap usage or whatever yo
|
||||
// NOTE: I need to add better logic for this. We need to detect pit stops
|
||||
// instead of just checking if the fuel is greater than before
|
||||
func (fc *FuelCalculator) refueled(fuel float64) bool {
|
||||
return fuel > fc.Laps[fc.CurrentLap].StartFuelLevel
|
||||
}
|
||||
|
||||
func (fc *FuelCalculator) Process(td *TelemetryData) {
|
||||
// This setup function will set the default values for the fields we work
|
||||
// with on this fuel calculator
|
||||
fc.setup.Do(func() {
|
||||
td.Values[FuelLastLap].Type = DataTypeSTRING
|
||||
td.Values[FuelLastLap].Str = "No Data"
|
||||
|
||||
td.Values[FuelCurrentLap].Type = DataTypeSTRING
|
||||
td.Values[FuelCurrentLap].Str = "No Data"
|
||||
fc.initializeFCTelemetryFields(td)
|
||||
})
|
||||
|
||||
currentLap := int(td.Values[LapNumber].Raw)
|
||||
scannedLap := int(td.Values[LapNumber].Raw)
|
||||
// NOTE: this is stupid as, fix it. I mean don't store fuel level as a string
|
||||
// currentFuelLevel, err := strconv.ParseFloat(td.Values[FuelLevel].Str, 64)
|
||||
scannedFuelLevel, err := strconv.ParseFloat(td.Values[FuelLevel].Str, 64)
|
||||
if err != nil {
|
||||
fc.Logger.Debug(fmt.Sprintf("error parsing fuel level: %+v", err))
|
||||
|
||||
switch fc.state {
|
||||
case outlap:
|
||||
fc.processOutlap(td, currentLap)
|
||||
case firstLap:
|
||||
fc.processFirstlap(td, currentLap)
|
||||
case normal:
|
||||
fc.processNormal(td, currentLap)
|
||||
td.Values[FCLastLap].Str = "ERROR"
|
||||
td.Values[FCCurrentLap].Str = "ERROR"
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Start the 0th lap
|
||||
if fc.CurrentLap == 0 && fc.Laps[0].StartFuelLevel == 0 {
|
||||
fc.newLapData(scannedLap, scannedFuelLevel)
|
||||
}
|
||||
|
||||
if fc.refueled(scannedFuelLevel) {
|
||||
fc.Laps[fc.CurrentLap].StartFuelLevel = scannedFuelLevel
|
||||
fc.Laps[fc.CurrentLap].InvalidateLap()
|
||||
}
|
||||
|
||||
if scannedLap > fc.CurrentLap {
|
||||
// Crossed the start finish line to the next lap
|
||||
fc.startFinishLineCrossed(td, scannedLap, scannedFuelLevel)
|
||||
}
|
||||
|
||||
fc.updateRealTimeVariables(td, scannedLap, scannedFuelLevel)
|
||||
}
|
||||
|
||||
// Simple helper to wipe state on session changes
|
||||
|
||||
Reference in New Issue
Block a user