Skip to content

Commit

Permalink
Implement telemetry tool
Browse files Browse the repository at this point in the history
  • Loading branch information
zh32 committed Jun 2, 2018
0 parents commit b24c469
Show file tree
Hide file tree
Showing 6 changed files with 495 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea/
34 changes: 34 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"drtelemetry/telemetry"
"os"
"os/signal"
"fmt"
"time"
"flag"
"log"
"drtelemetry/ui"
"syscall"
)

func main() {
fmt.Println("**********************************************")
fmt.Println("**** DiRT Rally Telemetry Overlay by zh32 ****")
fmt.Println("**********************************************")

flag.Parse()
log.SetFlags(0)

dataChannel, quit := telemetry.RunServer(":10001")
go ui.ListenAndServe(dataChannel)

c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
sig := <-c

fmt.Printf("captured %v, stopping profiler and exiting..", sig)
close(quit)
time.Sleep(2 * time.Second)
os.Exit(1)
}
140 changes: 140 additions & 0 deletions telemetry/telemetry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package telemetry

import (
"encoding/binary"
"bytes"
"net"
"fmt"
"flag"
)
/**
* Protocol specification: https://docs.google.com/spreadsheets/d/1UTgeE7vbnGIzDz-URRk2eBIPc_LR1vWcZklp7xD9N0Y/edit#gid=0
*/
type TelemetryData struct {
Time float32 `json:"time"`
LapTime float32 `json:"lapTime"`
LapDistance float32 `json:"lapDistance"`
TotalDistance float32 `json:"distance"`
X float32 `json:"-"` // World space position
Y float32 `json:"-"` // World space position
Z float32 `json:"-"` // World space position
Speed float32 `json:"speed"`
Xv float32 `json:"-"` // Velocity in world space
Yv float32 `json:"-"` // Velocity in world space
Zv float32 `json:"-"` // Velocity in world space
Xr float32 `json:"-"` // World space right direction
Yr float32 `json:"-"` // World space right direction
Zr float32 `json:"-"` // World space right direction
Xd float32 `json:"-"` // World space forward direction
Yd float32 `json:"-"` // World space forward direction
Zd float32 `json:"-"` // World space forward direction
Susp_pos_bl float32 `json:"-"`
Susp_pos_br float32 `json:"-"`
Susp_pos_fl float32 `json:"-"`
Susp_pos_fr float32 `json:"-"`
Susp_vel_bl float32 `json:"-"`
Susp_vel_br float32 `json:"-"`
Susp_vel_fl float32 `json:"-"`
Susp_vel_fr float32 `json:"-"`
Wheel_speed_bl float32 `json:"-"`
Wheel_speed_br float32 `json:"-"`
Wheel_speed_fl float32 `json:"-"`
Wheel_speed_fr float32 `json:"-"`
Throttle float32 `json:"throttlePosition"`
Steer float32 `json:"steerPosition"`
Brake float32 `json:"brakePosition"`
Clutch float32 `json:"clutchPosition"`
Gear float32 `json:"gear"`
Gforce_lat float32 `json:"-"`
Gforce_lon float32 `json:"-"`
Lap float32 `json:"-"`
EngineRate float32 `json:"rpm"`
Sli_pro_native_support float32 `json:"-"` // SLI Pro support
Car_position float32 `json:"-"` // car race position
Kers_level float32 `json:"-"` // kers energy left
Kers_max_level float32 `json:"-"` // kers maximum energy
Drs float32 `json:"-"` // 0 = off, 1 = on
Traction_control float32 `json:"-"` // 0 (off) - 2 (high)
Anti_lock_brakes float32 `json:"-"` // 0 (off) - 1 (on)
Fuel_in_tank float32 `json:"-"` // current fuel mass
Fuel_capacity float32 `json:"-"` // fuel capacity
In_pits float32 `json:"-"` // 0 = none, 1 = pitting, 2 = in pit area
Sector float32 `json:"-"` // 0 = sector1, 1 = sector2 float32 `json:"-"` 2 = sector3
Sector1_time float32 `json:"-"` // time of sector1 (or 0)
Sector2_time float32 `json:"-"` // time of sector2 (or 0)
Brakes_temp float32 `json:"-"` // brakes temperature (centigrade)
Wheels_pressure float32 `json:"-"` // wheels pressure PSI
Teainfo float32 `json:"-"` // team ID
Total_laps float32 `json:"-"` // total number of laps in this race
Track_size float32 `json:"-"` // track size meters
Last_lap_time float32 `json:"-"` // last lap time
Max_rpm float32 `json:"-"` // cars max RPM, at which point the rev limiter will kick in
Idle_rpm float32 `json:"-"` // cars idle RPM
Max_gears float32 `json:"-"` // maximum number of gears
SessionType float32 `json:"-"` // 0 = unknown, 1 = practice, 2 = qualifying, 3 = race
DrsAllowed float32 `json:"trackLength"` // 0 = not allowed, 1 = allowed, -1 = invalid / unknown
Track_number float32 `json:"-"` // -1 for unknown, 0-21 for tracks
VehicleFIAFlags float32 `json:"maxRpm"` // -1 = invalid/unknown, 0 = none, 1 = green, 2 = blue, 3 = yellow, 4 = red
}

var Addr = flag.String("udp", "localhost:10001", "udp service address")
var dataChannel = make(chan TelemetryData)

func ReadFromBytes(data []byte, telemetryData *TelemetryData) error {
buffer := bytes.NewBuffer(data)
if err := binary.Read(buffer, binary.LittleEndian, telemetryData); err != nil {
return err
}
return nil
}

func RunServer(host string) (chan TelemetryData, chan struct{}) {
quit := make(chan struct{})

go func() {
protocol := "udp"

udpAddr, err := net.ResolveUDPAddr(protocol, host)
if err != nil {
fmt.Println("Wrong Address")
return
}

udpConn, err := net.ListenUDP(protocol, udpAddr)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Listening for telemetry data on %s\n", *Addr)
defer udpConn.Close()

for {
select {
default:
HandleConnection(udpConn)
case <-quit:
fmt.Println("Stopping telemetry server")
return
}
}
}()

return dataChannel, quit
}

func HandleConnection(conn *net.UDPConn) {
buf := make([]byte, 264)
n, _, err := conn.ReadFromUDP(buf)
if err != nil {
fmt.Println("Error Reading")
fmt.Println(err)
return
} else {
var reader = bytes.NewBuffer(buf[:n])
var foo TelemetryData
err := binary.Read(reader, binary.LittleEndian, &foo)
if err != nil {
fmt.Println(err)
}
dataChannel <- foo
}
}
15 changes: 15 additions & 0 deletions telemetry/telemetry_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package telemetry

import "testing"

func TestDecode(t *testing.T) {
wireDump := []byte{0x28, 0x74, 0x6a, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x7e, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x98, 0x3f, 0x45, 0x4a, 0x34, 0xb4, 0xc2, 0x19, 0xf7, 0x24, 0x43, 0x44, 0x49, 0x48, 0x3b, 0x44, 0xf2, 0xdd, 0x3a, 0xe1, 0x57, 0x08, 0x3b, 0x11, 0xf0, 0xbf, 0xba, 0xb7, 0x39, 0x07, 0xbc, 0x3f, 0x69, 0x8a, 0x3b, 0x30, 0xfd, 0x7f, 0xbf, 0xeb, 0xf4, 0x7f, 0xbf, 0x93, 0xef, 0x86, 0xbc, 0x83, 0x11, 0x06, 0x3c, 0xad, 0xc3, 0x91, 0xc1, 0xda, 0x57, 0x95, 0xc1, 0x1e, 0x8c, 0x02, 0xc1, 0x0b, 0xe9, 0x02, 0xc1, 0xb5, 0x84, 0x86, 0xc2, 0x91, 0x43, 0x82, 0xc2, 0xcf, 0xa0, 0x43, 0xc2, 0xf5, 0x26, 0x3a, 0xc2, 0x29, 0xed, 0xa9, 0xaf, 0xb0, 0xb0, 0xb3, 0xb9, 0xa1, 0xdb, 0x23, 0x2f, 0x61, 0x01, 0xad, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x34, 0x4d, 0x43, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x05, 0xa0, 0x41, 0xa0, 0x05, 0xa0, 0x41, 0xa0, 0x05, 0xa0, 0x41, 0xa0, 0x05, 0xa0, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x14, 0x30, 0x8f, 0x45, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x59, 0x44, 0x44, 0x1a, 0x34, 0x4c, 0x43, 0x00, 0x00, 0xa0, 0x40}
var data TelemetryData
err := ReadFromBytes(wireDump, &data)
if err != nil {
t.Error(err)
}
if data.EngineRate != 205.20612 {
t.Error("Could not read correct engine RPM")
}
}
Loading

0 comments on commit b24c469

Please sign in to comment.