First commit
It works like this
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
# BeamNG SDK
|
||||
Simple SDK to interact with BeamNG.drive OutGauge data.
|
||||
@@ -0,0 +1,89 @@
|
||||
package bngsdk
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
const (
|
||||
UDP_IP = "127.0.0.1"
|
||||
UDP_PORT = 4444
|
||||
)
|
||||
|
||||
type BNGSDK struct {
|
||||
Addr *net.UDPAddr
|
||||
Conn *net.UDPConn
|
||||
Buffer []byte
|
||||
Data *Outgauge
|
||||
DataDict map[string]interface{}
|
||||
}
|
||||
|
||||
func createUDPConnection(ip string, port int) (*net.UDPConn, *net.UDPAddr, error) {
|
||||
// Define the IP address and port to listen on
|
||||
addr := &net.UDPAddr{
|
||||
IP: net.ParseIP(ip),
|
||||
Port: port,
|
||||
}
|
||||
|
||||
// Create a UDP socket
|
||||
conn, err := net.ListenUDP("udp", addr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return conn, addr, nil
|
||||
}
|
||||
|
||||
// ReadData will read new data from the UDP server
|
||||
func (sdk *BNGSDK) ReadData() error {
|
||||
// Receive data from the socket
|
||||
n, _, err := sdk.Conn.ReadFromUDP(sdk.Buffer)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading from UDP:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if enough data was received to fill our struct
|
||||
if n < binary.Size(Outgauge{}) {
|
||||
fmt.Println("Received packet too small for Outgauge struct")
|
||||
return err
|
||||
}
|
||||
|
||||
// Read the binary data into the struct
|
||||
reader := bytes.NewReader(sdk.Buffer[:n])
|
||||
if err := binary.Read(reader, binary.LittleEndian, sdk.Data); err != nil {
|
||||
fmt.Println("Error decoding UDP packet:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Update the local map
|
||||
sdk.DataDict = sdk.Data.ToMap()
|
||||
|
||||
// this means there's new data
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sdk *BNGSDK) Close() {
|
||||
sdk.Conn.Close()
|
||||
}
|
||||
|
||||
// Init initializes a BeamNG SDK struct
|
||||
func Init(ip string, port int) (BNGSDK, error) {
|
||||
var err error
|
||||
sdk := BNGSDK{}
|
||||
|
||||
// Create the connection to the OutGauge server
|
||||
sdk.Conn, sdk.Addr, err = createUDPConnection(ip, port)
|
||||
if err != nil {
|
||||
return BNGSDK{}, err
|
||||
}
|
||||
|
||||
// Initiate the data variables
|
||||
sdk.Buffer = make([]byte, 1024)
|
||||
sdk.Data = &Outgauge{}
|
||||
sdk.DataDict = sdk.Data.ToMap()
|
||||
|
||||
return sdk, nil
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module bngsdk
|
||||
|
||||
go 1.22.0
|
||||
|
||||
require github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07
|
||||
|
||||
require golang.org/x/sys v0.26.0 // indirect
|
||||
@@ -0,0 +1,4 @@
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package bngsdk
|
||||
|
||||
/* TODO
|
||||
- OG_x Flags
|
||||
- DL_x Flags
|
||||
*/
|
||||
|
||||
// More documentation at https://go.beamng.com/protocols
|
||||
type Outgauge struct {
|
||||
Time uint32 // time in milliseconds (to check order)
|
||||
Car [4]byte // Car name
|
||||
Flags uint16 // Info (see OG_x below)
|
||||
Gear int8 // Reverse:0, Neutral:1, First:2...
|
||||
Plid int8 // Unique ID of viewed player (0 = none)
|
||||
Speed float32 // M/S
|
||||
RPM float32 // RPM
|
||||
Turbo float32 // BAR
|
||||
EngTemp float32 // C
|
||||
Fuel float32 // 0 to 1
|
||||
OilPressure float32 // BAR
|
||||
OilTemp float32 // C
|
||||
DashLights uint32 // Dash lights available (see DL_x below)
|
||||
ShowLights uint32 // Dash lights currently switched on
|
||||
Throttle float32 // 0 to 1
|
||||
Brake float32 // 0 to 1
|
||||
Clutch float32 // 0 to 1
|
||||
Display1 [16]byte // Usually Fuel
|
||||
Display2 [16]byte // Usually Settings
|
||||
ID int32 // optional - only if OutGauge ID is specified
|
||||
}
|
||||
|
||||
func (o *Outgauge) ToMap() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"Time": o.Time, // time in milliseconds (to check order)
|
||||
"Car": o.Car, // Car name
|
||||
"Flags": o.Flags, // Info (see OG_x below)
|
||||
"Gear": o.Gear, // Reverse:0, Neutral:1, First:2...
|
||||
"Plid": o.Plid, // Unique ID of viewed player (0 = none)
|
||||
"Speed": o.Speed, // M/S
|
||||
"RPM": o.RPM, // RPM
|
||||
"Turbo": o.Turbo, // BAR
|
||||
"EngTemp": o.EngTemp, // C
|
||||
"Fuel": o.Fuel, // 0 to 1
|
||||
"OilPressure": o.OilPressure, // BAR
|
||||
"OilTemp": o.OilTemp, // C
|
||||
"DashLights": o.DashLights, // Dash lights available (see DL_x below)
|
||||
"ShowLights": o.ShowLights, // Dash lights currently switched on
|
||||
"Throttle": o.Throttle, // 0 to 1
|
||||
"Brake": o.Brake, // 0 to 1
|
||||
"Clutch": o.Clutch, // 0 to 1
|
||||
"Display1": o.Display1, // Usually Fuel
|
||||
"Display2": o.Display2, // Usually Settings
|
||||
"ID": o.ID, // optional - only if OutGauge ID is specified
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user