Building My Own Telemetry System for F1 2017 (Game) Using Golang, InfluxDB and Grafana.

Intro

Some day ago, I discovered a feature in my F1 2017 Game(PS4), navigating in a menu I sow an option called UDP Telemetry Settings with many network configurations, as shown below.

UDP Telemetry Settings in F1 2017

After, I searched at Google about that and I found a blog post at Codemasters Blog with the specification about that UDP package. Yes, that is a great example of poor documentation, only a Struct scheme with wrong information's fixed in commentaries below of the post. The struct is shown below.

// Packet size – 1289 bytes
struct UDPPacket
{
float m_time;
float m_lapTime;
float m_lapDistance;
float m_totalDistance;
float m_x; // World space position
float m_y; // World space position
float m_z; // World space position
float m_speed; // Speed of car in MPH //First mistake, the speed is measured in m/s
.........
See the full struct at the blog post : http://forums.codemasters.com/discussion/53139/f1-2017-d-box-and-udp-output-specification

After I knew how to work that feature I created a simple go program for reading the packages and printing the speed of the car. In my program I had to read some bytes from the UDP payload, Obs: all Floats fields have 4 bytes and Int’s values have a byte.

Yes, Only seeing speed in a terminal is not useful, I needed find a good way to see those information's and I thought in a good tool used for monitoring servers and applications, If you thought about Grafana you are right.

Grafana can make Beautiful dashboards with a lot of graphs, It can manipulate data and it’s perfect to monitoring things in real time like software applications but now a will test with a Formula 1 car ;).

Grafana Dashboard (at Github project)

The first thing that I did was to understand how I can send data to Grafana. In my search I found many Data Sources but only 10 oficial Data Sources, In those Data Sources I chose the InfluxDB because it’s fast, easy and I don’t need use a collector for sending my data to DB.

With those 3 tools I did my own telemetry system.

F1 Dashboard

First Step: Make a Collector

First, I need write a collector who will collect data in UDP packages and after will send to InfluxDB, Is easy speak this but I found same issues for building that.

The first problem we need solve is how to read UDP packages, It’s simple in Go, we can use the package net, in this package have the function ListUDP witch open a UDP connection, after that we need build a loop and use the Read function of the connection for reading the bytes of UDP payload. Obs: I created a buffer with 1289 bytes because is the size described in F1 documentation.

After read the UDP package we need converter to a struct witch describe the information's about the car or race, So the next step is write structs, we have 2 struct, the first describe you and the second describe other players.

Now with the complete structs We need decode the binary package in a TelemetryPack, It’s easy too. We can use the ‘encode/binary’ package of Go. In that have a function named Read who transform the binary in a struct. We can just write a New function in telemetry.go file.

After that we need write a simple client for sending the struct in InfluxDB, believe It’s easy too.

I need give a few explications about that code, first I created a UDPClient who will send the data to InfluxDB, after I initialized a loop with channel and created a BatchPoints, BatchPoints is an interface into a batched grouping of points to write into InfluxDB together but in this exemple we will write one per one because we need more speed in the graph view.

After created a BatchPoints I created Point who represents a single data point, Lastly I sent the BatchPoints to server with write function.

At this moment we have three different parts of our collector, an UDP receiver, the Struct and an InfluxDB client. Now we need to make it all work together, first we will do the receiver to transform a UDP pack to a TelemetryPack and make a Point with that.

For that, We need convert the struct to a map of strings, I wrote a special function using the package reflect for that.

Now miss simple things, We need call that function in client.NewPoint

influxdb.go complete

And for finish, we need send the struct for our client, for that I initialized 5 go routines with influxDBSender and in loop I created and sent a Point struct to channel.

For seeing all code go to my github project.

Second Step: Install The InfluxDB

Now we need install a InfluxDB server in a host, In this post I’am using a Raspberry pi 3 b+ as host for my Grafana and InfluxDB. It’s very easy install that Raspbian, We need add the InfluxData repository at apt and after run a apt-get , we can do this with these commands:

If you want know more about that follow the oficial documentation at https://docs.influxdata.com/influxdb/v1.5/introduction/installation .

After that we have a InfluxDB server running in our host, but it don’t allow UDP packages yet, for configure that we need make some changes at influxdb.conf, only change the UDP enabled for true, uncomment bind-address and put database line with name of our database (“f1”).

[[udp]]
enabled = true
bind-address = ":8089"
database = "f1"
.........

Now Enough restart the server and create the f1 database with these commands.

influx
>> CREATE DATABASE f1
>> exit

Third Step: Install The Grafana

Simple, follow that page http://docs.grafana.org/installation/debian/ .

I installed with these commands:

wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.2.1_armhf.deb 
sudo dpkg -i grafana_5.2.1_armhf.deb
sudo service grafana-server start

Is it, if you try access the port 3000 with user admin/admin you can acesse the Grafana.

First thing to do is configure the data source.

Fourth Step: Configure Our First Dashboard

The InfluxDB only create the schema after receive the first message, we need try all for that, play the F1 game and run our Golang program.

Now we have all done to make our first dashbord.

It’s simple, click in create a new dashboard -> add panel-> graph -> edit, after just add that configuration:

And now, we have our first dash with a speed graph. Enjoy it.

Now just study about Grafana and make you dashboad.

Final

In that post I showed to you how I can make my own telemetry system, it’s the basic, if you want more see my github repo.

https://github.com/rafaelreinert/F1

If you think it ‘s useless. You are correct. But I improve my english writing this post, I learned about Grafana and Influxdb and It’s first time I use UDP and Reflect in Go. All of it in a cool project(for me).