Working on some standings

This commit is contained in:
2025-01-16 20:18:05 +00:00
parent 4713fc80eb
commit c5ff9f95c9
3 changed files with 126 additions and 14 deletions
+2
View File
@@ -3,6 +3,8 @@
- [x] Read data from a stored `.ibt` file
- [x] Allow to export the data to an `.ibt` file
- [x] Allow to export the session info data to a `.yaml` file
- [ ] Make sure variables with multiple counts are correctly parsed and stored
- [ ] Correctly support and implement the bitFields data
- [ ] Add the message broadcasting system
- [ ] Explore a more convenient API for fetching the data for the SDK user
- [ ] Change the pattern in which the data is fetched from the telemetry and
+24 -3
View File
@@ -1,13 +1,20 @@
package goirsdk
import (
"fmt"
"fmt"
"log"
"os"
"sort"
"testing"
"time"
)
type StandingsLine struct {
CarIdx int
LapPct float32
DriverName string
}
func TestFunctionality(t *testing.T) {
input, err := os.Open("../testTelemetry/supercars_race_watkins_glenn.ibt")
if err != nil {
@@ -35,17 +42,31 @@ func TestFunctionality(t *testing.T) {
if _, ok := i.Vars.Vars["CarIdxPosition"]; !ok {
log.Fatal("Field `CarIdxPosition` doesn't exist")
}
driversPositions := i.Vars.Vars["CarIdxPosition"].Value.([]int)
driversPositions := i.Vars.Vars["CarIdxLapDistPct"].Value.([]float32)
drivers := i.SessionInfo.DriverInfo.Drivers
standings := make([]StandingsLine, len(drivers))
fmt.Printf("\033[?25l\033[2J\033[H")
for k := range len(drivers) {
if drivers[k].CarIsPaceCar == 1 || drivers[k].IsSpectator == 1 {
continue
}
fmt.Printf("[%d] [%d] %s\n", k, driversPositions[drivers[k].CarIdx], drivers[k].UserName)
standings[k] = StandingsLine{
CarIdx: k,
LapPct: float32(driversPositions[k]),
DriverName: drivers[k].UserName,
}
}
sort.Slice(standings, func(i int, j int) bool {
return standings[i].LapPct >= standings[j].LapPct
})
for p, v := range standings {
fmt.Printf("[%d] %s %f\n", p + 1, v.DriverName, v.LapPct)
}
<-mainLoopTicker.C
+100 -11
View File
@@ -71,6 +71,20 @@ type Var struct {
Value interface{}
}
func (v *Var) ToString() string {
return fmt.Sprintf(
"Type: %5d (0x%08x)\n"+
"Offset: %5d (0x%08x)\n"+
"Count: %5d (0x%08x)\n"+
"CountAsTime: %5t\n"+
"Name: %s\n"+
"Description: %s\n"+
"Unit: %s",
v.Type, v.Type, v.Offset, v.Offset, v.Count, v.Count,
v.CountAsTime, v.Name, v.Description, v.Unit,
)
}
func (v *IBTVar) ToString() string {
return fmt.Sprintf(
"Type: %5d (0x%08x)\n"+
@@ -147,29 +161,103 @@ func (i *IBT) readData(buf []byte) error {
// Read the value
switch v.Type {
case IRSDK_char:
v.Value = string(rbuf[0])
case IRSDK_bool:
v.Value = int(rbuf[0]) > 0
case IRSDK_int:
if v.Count > 1 {
data := make([]int, v.Count)
// Array of data
data := make([]string, v.Count)
for entry := 0; entry < int(v.Count); entry++ {
entryOffset := v.Offset + int32(entry)*int32(VarTypes[int(v.Type)].Size)
rbuf := buf[entryOffset : entryOffset+int32(VarTypes[int(v.Type)].Size)]
newValue := int(binary.LittleEndian.Uint32(rbuf))
newValue := string(rbuf[0])
data[entry] = newValue
}
v.Value = data
} else {
// Single value
v.Value = string(rbuf[0])
}
case IRSDK_bool:
if v.Count > 1 {
// Array of data
data := make([]bool, v.Count)
for entry := 0; entry < int(v.Count); entry++ {
entryOffset := v.Offset + int32(entry)*int32(VarTypes[int(v.Type)].Size)
rbuf := buf[entryOffset : entryOffset+int32(VarTypes[int(v.Type)].Size)]
newValue := int(rbuf[0]) > 0
data[entry] = newValue
}
v.Value = data
} else {
// Single value
v.Value = int(rbuf[0]) > 0
}
case IRSDK_int:
if v.Count > 1 {
// Array of data
data := make([]int32, v.Count)
for entry := 0; entry < int(v.Count); entry++ {
entryOffset := v.Offset + int32(entry)*int32(VarTypes[int(v.Type)].Size)
rbuf := buf[entryOffset : entryOffset+int32(VarTypes[int(v.Type)].Size)]
newValue := int32(binary.LittleEndian.Uint32(rbuf))
data[entry] = newValue
}
v.Value = data
} else {
// Single value
v.Value = int(binary.LittleEndian.Uint32(rbuf))
}
case IRSDK_bitField:
v.Value = fmt.Sprintf("0x%x", int(binary.LittleEndian.Uint32(rbuf)))
if v.Count > 1 {
// Array of data
data := make([]string, v.Count)
for entry := 0; entry < int(v.Count); entry++ {
entryOffset := v.Offset + int32(entry)*int32(VarTypes[int(v.Type)].Size)
rbuf := buf[entryOffset : entryOffset+int32(VarTypes[int(v.Type)].Size)]
newValue := fmt.Sprintf("0x%x", int(binary.LittleEndian.Uint32(rbuf)))
data[entry] = newValue
}
v.Value = data
} else {
// Single value
v.Value = fmt.Sprintf("0x%x", int(binary.LittleEndian.Uint32(rbuf)))
}
case IRSDK_float:
v.Value = math.Float32frombits(uint32(binary.LittleEndian.Uint32(rbuf)))
if v.Count > 1 {
// Array of data
data := make([]float32, v.Count)
for entry := 0; entry < int(v.Count); entry++ {
entryOffset := v.Offset + int32(entry)*int32(VarTypes[int(v.Type)].Size)
rbuf := buf[entryOffset : entryOffset+int32(VarTypes[int(v.Type)].Size)]
newValue := math.Float32frombits(uint32(binary.LittleEndian.Uint32(rbuf)))
data[entry] = newValue
}
v.Value = data
} else {
// Single value
v.Value = math.Float32frombits(uint32(binary.LittleEndian.Uint32(rbuf)))
}
case IRSDK_double:
v.Value = math.Float64frombits(uint64(binary.LittleEndian.Uint64(rbuf)))
if v.Count > 1 {
// Array of data
data := make([]float64, v.Count)
for entry := 0; entry < int(v.Count); entry++ {
entryOffset := v.Offset + int32(entry)*int32(VarTypes[int(v.Type)].Size)
rbuf := buf[entryOffset : entryOffset+int32(VarTypes[int(v.Type)].Size)]
newValue := math.Float64frombits(uint64(binary.LittleEndian.Uint64(rbuf)))
data[entry] = newValue
}
v.Value = data
} else {
// Single value
v.Value = math.Float64frombits(uint64(binary.LittleEndian.Uint64(rbuf)))
}
}
// --------------
@@ -236,6 +324,7 @@ func (i *IBT) Update(timeout time.Duration) (IRacingState, error) {
return Ended, nil
}
// Document why this is here, I don't remember the exact words right now
i.Vars.RecorderTick++
} else {
// This will get the dataframe corresponding to a given tick
@@ -245,12 +334,12 @@ func (i *IBT) Update(timeout time.Duration) (IRacingState, error) {
// Make this happen in a different thread, or have this send to a queue that has a thread
// writing to a file
if i.IBTExport != nil {
if i.IBTExport != nil {
err = i.exportIBT(buf, int64(start))
if err != nil {
log.Printf("Failed to export offline telemetry data: %v", err)
}
}
}
if err == io.EOF {
return Ended, nil