This commit is contained in:
2025-02-03 23:56:58 +00:00
parent 88a0251b2d
commit 977e5e4b38
3 changed files with 153 additions and 63 deletions
+9 -9
View File
@@ -23,17 +23,17 @@ func (e *ESDI) Close() {
}
func ESDIInit(port string, baud int) (ESDI, error) {
// sConfig := &serial.Config{
// Name: port,
// Baud: baud,
// }
sConfig := &serial.Config{
Name: port,
Baud: baud,
}
// Open the serial port
// sPort, err := serial.OpenPort(sConfig)
// if err != nil {
// return ESDI{}, err
// }
sPort, err := serial.OpenPort(sConfig)
if err != nil {
return ESDI{}, err
}
// return ESDI{sConfig, sPort, nil}, nil
return ESDI{nil, nil, nil, DataPacket{}}, nil
return ESDI{sConfig, sPort, nil, DataPacket{}}, nil
}
+119 -41
View File
@@ -12,7 +12,7 @@ import (
"syscall"
"time"
"github.com/tarm/serial"
// "github.com/tarm/serial"
)
type GameSource interface {
@@ -37,12 +37,12 @@ type DataPacket struct {
FuelLiters float32
FuelTotal float32 // This will be calculated and passed in Liters
Position int32
Standings []StandingsLine
Standings [5]StandingsLine
}
var (
paddingStandingsLine = StandingsLine{
DriverName: "---",
DriverName: createDriverName("---"),
Lap: 0,
CarIdx: 0,
LapPct: 0,
@@ -91,7 +91,7 @@ func resetTerminal() {
fmt.Print("\033[?25h\033[2J\033[H")
}
func (e *ESDI) setupSignalHandlers() chan struct{} {
func (e *ESDI) setupSignalHandlers() chan string {
sigc := make(chan os.Signal, 1)
signal.Notify(sigc,
syscall.SIGHUP,
@@ -99,7 +99,7 @@ func (e *ESDI) setupSignalHandlers() chan struct{} {
syscall.SIGTERM,
syscall.SIGQUIT,
)
done := make(chan struct{})
done := make(chan string)
go func() {
s := <-sigc
@@ -114,33 +114,48 @@ func (e *ESDI) setupSignalHandlers() chan struct{} {
return done
}
func sendData(e *ESDI, s *serial.Port, done <-chan struct{}) {
ticker := time.NewTicker(time.Millisecond * 25)
defer ticker.Stop()
// func sendData(e *ESDI, s *serial.Port, done <-chan string, errC chan string) {
// ticker := time.NewTicker(time.Millisecond * 25)
// defer ticker.Stop()
//
// for {
// select {
// case <-done:
// return
// case <-ticker.C:
// mu.Lock()
//
// data := DataToSend{
// Speed: e.data.Speed,
// Gear: e.data.Gear,
// RPM: e.data.RPM,
// LapCount: e.data.LapCount,
// LapDistPct: e.data.LapDistPct,
// // FuelPerLap: e.data.FuelPerLap,
// // FuelUsageCurLap: e.data.FuelUsageCurLap,
// }
//
// copy(data.LapTime[:], e.data.LapTime[:])
// copy(data.LapDelta[:], e.data.LapDelta[:])
// copy(data.BestLapTime[:], e.data.BestLapTime[:])
// copy(data.LastLapTime[:], e.data.LastLapTime[:])
//
// var buf bytes.Buffer
// err := binary.Write(&buf, binary.LittleEndian, data)
//
// _, err = s.Write(buf.Bytes())
// if err != nil {
// log.Printf("Unable to write data: %v", err)
// break
// }
//
// lastMessageTime = time.Now()
// mu.Unlock()
// }
// }
// }
for {
select {
case <-done:
return
case <-ticker.C:
mu.Lock()
var buf bytes.Buffer
err := binary.Write(&buf, binary.LittleEndian, e.data)
_, err = s.Write(buf.Bytes())
if err != nil {
log.Printf("Unable to write data: %v", err)
break
}
lastMessageTime = time.Now()
mu.Unlock()
}
}
}
func printData(e *ESDI, done <-chan struct{}) {
func printData(e *ESDI, done <-chan string) {
ticker := time.NewTicker(time.Millisecond * 25)
defer ticker.Stop()
@@ -153,21 +168,28 @@ func printData(e *ESDI, done <-chan struct{}) {
buffer.WriteString("\033[?25l\033[2J\033[H")
mu.Lock()
buffer.WriteString(fmt.Sprintf("Gear: %d, RPM: %d, Speed: %d\n",
buffer.WriteString("Car data:\n")
buffer.WriteString(fmt.Sprintf("Gear: %d, RPM: %d, Speed: %d\n\n",
e.data.Gear, e.data.RPM, e.data.Speed))
buffer.WriteString(fmt.Sprintf("Fuel: %.2fL/%.2fL %.2f/lap [%.2f%%]\n", e.data.FuelLiters,
buffer.WriteString("Fuel data:\n")
buffer.WriteString(fmt.Sprintf("Fuel: %.2fL/%.2fL %.2f/lap [%.2f%%]\n\n", e.data.FuelLiters,
e.data.FuelTotal, e.data.FuelPerLap, e.data.FuelPct))
buffer.WriteString("Lap data:\n")
buffer.WriteString(fmt.Sprintf("LapTime: %s [%s]\n", e.data.LapTime,
e.data.LapDelta))
buffer.WriteString(fmt.Sprintf("Best Lap Time: %s\n", e.data.BestLapTime))
buffer.WriteString(fmt.Sprintf("Last Lap Time: %s\n", e.data.LastLapTime))
buffer.WriteString(fmt.Sprintf("Lap: %d [%.2f%%]\n", e.data.LapCount,
buffer.WriteString(fmt.Sprintf("Lap: %d [%.2f%%]\n\n", e.data.LapCount,
e.data.LapDistPct))
buffer.WriteString("Position data:\n")
buffer.WriteString(fmt.Sprintf("Pos: %d\n", e.data.Position))
for p, v := range e.data.Standings {
s := fmt.Sprintf("[%2d] [%2d]%-30s %3d %10f %s\n",
p+1, v.CarIdx, v.DriverName, v.Lap, v.LapPct, lapTimeRepresentation(v.TimeBehind))
s := fmt.Sprintf("[%2d] [%2d] %-16s %3d %10f %s\n",
p+1, v.CarIdx, string(bytes.Trim(v.DriverName[:], "\x00")), v.Lap, v.LapPct, v.TimeBehindString)
buffer.WriteString(s)
}
mu.Unlock()
@@ -232,7 +254,7 @@ func (e *ESDI) positionData() {
standings := createStandingsTable(e.irsdk)
relativeStandings(e.irsdk, standings, e.irsdk.SessionInfo.DriverInfo.DriverCarIdx)
p := findEntry(standings, func(l StandingsLine) bool {
return l.CarIdx == e.irsdk.SessionInfo.DriverInfo.DriverCarIdx
return l.CarIdx == int32(e.irsdk.SessionInfo.DriverInfo.DriverCarIdx)
})
lowerLim := p - 2
@@ -260,16 +282,37 @@ func (e *ESDI) positionData() {
standings = append(standings, upperPadding...)
mu.Lock()
e.data.Standings = standings
copy(e.data.Standings[:], standings[0:5])
e.data.Position = int32(p)
mu.Unlock()
}
type DataToSend struct {
Speed int32
Gear int32
RPM int32
LapCount int32
LapDistPct float32
LapTime [16]byte // Current lap time
LapDelta [16]byte // Delta to selected reference lap
BestLapTime [16]byte // Best lap in session
LastLapTime [16]byte // Last lap time
FuelUsageCurLap float32
FuelPerLap float32
// FuelPct float32
// FuelLiters float32
// FuelTotal float32 // This will be calculated and passed in Liters
// Position int32
// Standings [5]StandingsLine
}
func (e *ESDI) telemetry() {
// Set the handlers
done := e.setupSignalHandlers()
// go sendData(e.SerialConn, done)
dataError := make(chan string)
// go sendData(e, e.SerialConn, done, dataError)
go printData(e, done)
mainLoopTicker := time.NewTicker(time.Second / 60)
@@ -279,10 +322,12 @@ func (e *ESDI) telemetry() {
for {
select {
case <-done:
case s := <-done:
resetTerminal()
fmt.Println("Quitting ESDI...")
fmt.Println(s)
return
case s := <-dataError:
done <- s
case <-mainLoopTicker.C:
time.Sleep(time.Second / 60)
@@ -298,6 +343,39 @@ func (e *ESDI) telemetry() {
e.fuelData()
e.lapData()
e.positionData()
mu.Lock()
data := DataToSend{
Speed: e.data.Speed,
Gear: e.data.Gear,
RPM: e.data.RPM,
LapCount: e.data.LapCount,
LapDistPct: e.data.LapDistPct,
// FuelPerLap: e.data.FuelPerLap,
// FuelUsageCurLap: e.data.FuelUsageCurLap,
}
copy(data.LapTime[:], e.data.LapTime[:])
copy(data.LapDelta[:], e.data.LapDelta[:])
copy(data.BestLapTime[:], e.data.BestLapTime[:])
copy(data.LastLapTime[:], e.data.LastLapTime[:])
var buf bytes.Buffer
err = binary.Write(&buf, binary.LittleEndian, data)
if len(buf.Bytes()) != 92 {
panic(fmt.Sprintf("Size is: %d, instead of 92", len(buf.Bytes())))
}
_, err = e.SerialConn.Write(buf.Bytes())
if err != nil {
log.Printf("Unable to write data: %v", err)
break
}
lastMessageTime = time.Now()
mu.Unlock()
}
}
}
+25 -13
View File
@@ -7,15 +7,27 @@ import (
)
type StandingsLine struct {
CarIdx int
LapPct float32
Lap int32
DriverName string
EstTime float32
TimeBehind float32
CarIdx int32
LapPct float32
Lap int32
DriverName [16]byte
EstTime float32
TimeBehind float32
TimeBehindString [16]byte
}
type standingsFilter func([]StandingsLine, []float32, int)
func createDriverName(s string) [16]byte {
var arr [16]byte
if len(s) > 32 {
s = s[:32]
}
copy(arr[:], s)
return arr
}
// type standingsFilter func([]StandingsLine, []float32, int)
func generalStandings(i *goirsdk.IBT, s []StandingsLine, id int) {
// We have to sort the racists by their lap count and position on the track
@@ -27,7 +39,7 @@ func generalStandings(i *goirsdk.IBT, s []StandingsLine, id int) {
return s[i].Lap > s[j].Lap
})
estTime := i.Vars.Vars["CarIdxEstTime"].Value.([]float32)
estTime := i.Vars.Vars["CarIdxEstTime"].Value.([]float32)
// This will give the delta to the guy ahead
// P1 0:00:000
@@ -41,6 +53,7 @@ func generalStandings(i *goirsdk.IBT, s []StandingsLine, id int) {
}
s[p].TimeBehind = theThing
copy(s[p].TimeBehindString[:], string(lapTimeRepresentation(theThing)))
}
}
@@ -52,7 +65,7 @@ func relativeStandings(i *goirsdk.IBT, s []StandingsLine, id int) {
return s[i].LapPct > s[j].LapPct
})
estTime := i.Vars.Vars["CarIdxEstTime"].Value.([]float32)
estTime := i.Vars.Vars["CarIdxEstTime"].Value.([]float32)
// Get the delta to a given carId
for p := range s {
@@ -62,6 +75,7 @@ func relativeStandings(i *goirsdk.IBT, s []StandingsLine, id int) {
delta = abs(estTime[id] - curCarEstimate)
s[p].TimeBehind = delta
copy(s[p].TimeBehindString[:], string(lapTimeRepresentation(delta)))
}
}
@@ -98,9 +112,9 @@ func createStandingsTable(i *goirsdk.IBT) []StandingsLine {
}
standings[k] = StandingsLine{
CarIdx: k,
CarIdx: int32(k),
LapPct: driversLapDistPct[k],
DriverName: drivers[k].UserName,
DriverName: createDriverName(drivers[k].UserName),
EstTime: driversEstTime[k],
Lap: driversLap[k],
TimeBehind: 0,
@@ -118,7 +132,5 @@ func abs[V int32 | float32 | int](value V) V {
return value
}
func getPlayerPosition(s []StandingsLine, p int) {
}