F1 2017 D-Box and UDP Output Specification

The F1 series of games support output
of game data to external devices such as D-BOX, other motion platforms,
steering wheels and LED devices that are connected to your PC or console. The
purpose of this document is to summarise the data that is outputted so that developers
of supporting hardware or software are able to configure these to work with the
F1 game correctly.

D-BOX output is currently
supported on the PC platform. In F1 2017, the D-BOX activation is controlled
via the menus instead of the hardware settings config file. Navigate to Game Options->Settings->UDP Telemetry
Settings->D-BOX to activate this on your system.

Enabling the UDP Telemetry Output

In F1 2017, UDP telemetry output
is controlled via the menus on all platforms. To
enable this, enter the options menu from the main menu (triangle / Y),
then enter the settings menu - the UDP option will be at the bottom of the
list. From there you will be able to enable / disable the UDP output, configure
the IP address and port for the receiving application, toggle broadcast mode
and set the send rate. Broadcast mode transmits the data across the network subnet
to allow multiple devices on the same subnet to be able to receive this information.
When using broadcast mode it is not necessary to set a target IP address, just
a target port for applications to listen on.

Advanced PC Users

You can additionally edit the game’s configuration XML file to configure UDP output. The file is located here (after an initial boot of the game):

Comments

The data is sent as
raw data in the UDP packet, converted to a char array, with packing enabled (no padding to align different
sized types). To decode
this into something usable it should be a case of casting the packet data back
to the UDPPacket struct (or another
structure with the same layout). The layout of the UDP data is as follows:

// 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

float m_xv; // Velocity in world space

float m_yv; // Velocity in world space

float m_zv; // Velocity in world space

float m_xr; // World space right direction

float m_yr; // World space right direction

float m_zr; // World space right direction

float m_xd; // World space forward direction

float m_yd; // World space forward direction

float m_zd; // World space forward direction

float m_susp_pos[4]; // Note: All wheel arrays have the order:

float m_susp_vel[4]; // RL, RR, FL, FR

float m_wheel_speed[4];

float m_throttle;

float m_steer;

float m_brake;

float m_clutch;

float m_gear;

float m_gforce_lat;

float m_gforce_lon;

float m_lap;

float m_engineRate;

float m_sli_pro_native_support; // SLI Pro support

float m_car_position; // car race position

float m_kers_level; // kers energy left

float m_kers_max_level; // kers maximum energy

float m_drs; // 0 = off, 1 = on

float m_traction_control; // 0 (off) - 2 (high)

float m_anti_lock_brakes; // 0 (off) - 1 (on)

float m_fuel_in_tank; // current fuel mass

float m_fuel_capacity; // fuel capacity

float m_in_pits; // 0 = none, 1 = pitting, 2 = in pit area

float m_sector; // 0 = sector1, 1 = sector2, 2 = sector3

float m_sector1_time; // time of sector1 (or 0)

float m_sector2_time; // time of sector2 (or 0)

float m_brakes_temp[4]; // brakes temperature (centigrade)

float m_tyres_pressure[4]; // tyres pressure PSI

float m_team_info; // team ID

float m_total_laps; // total number of laps in this race

float m_track_size; // track size meters

float m_last_lap_time; // last lap time

float m_max_rpm; // cars max RPM, at which point the rev limiter will kick in

Hi Hoo,I have managed to spend some time implementing and testing the new interface. Overall its a great improvement over what was available in F1 2016, so i think other integrators will also be quite happy with what they now have access to.

That being said, i do have some comments/issues/suggestions to note. In no particular order..

First up is the structure packing. In your UDP Packet Structure post you said "The data is sent as raw data in the UDP packet, converted to a char array, with packing disabled.", however this is incorrect as the data being sent is actually packed. I looked back on my earlier post back in the F1 2016 forum and noticed that i had referred to structure packing, when i intended to say structure padding, im not sure if this has had any impact on the packing decision. I guess it can be done either way, however NOT packing seems to be the preferred method as it removes any potential endianess issues associated with decoding packed data at the other end at the expense of potentially larger data. In this case with packing disabled there would only be two bytes of padding inserted at position 330 (which is right before the start of the participants array, as it is currently unaligned there). A decision will need to be made one way or the other on this, all i can say is my preference would be packing disabled which is also inline with what project cars does with its udp telemetry. Otherwise you could manually pad it by adding two reserved bytes right before the participants array so that everything is perfectly aligned, however you would still need to remember this in future if more changes are made.

We could do with car enums for all the historic cars, as currently when using a historic car there is no way to know in the telemetry what car it is. The existing team enum could perhaps just be extended (with a higher range set aside, eg 50+) for custom team/car identifiers that we can map to the correct car names.

Could we have the players login name included in the telemetry? I see "cjorgens79" showing up in game, it would be very useful to have this in the telemetry for displaying the player's name against other participants. I also intend to link the telemetry to my new cloud service which keeps a record of session/lap details from every lap driven in any game that RS Dash links to. Having the player name as seen in game will make it easier to do friend/opponent lookups in the cloud service for users. It not the end of the world if you cant, i can force the user to enter it online themselves to deal with it if its not practical.

While we get values in the telemetry for the following fields, their values never change.

- Tyre Temp

- Tyre Pressure

- Brake Temp

- Fuel (i suspect but havent yet tested that this one changes based on starting fuel load, but it certainly doesn't decrease while driving)

- Engine Temp

- Damage (I assume eventually this will be able to be turned on in the settings?)

We currently have telemetry indicators for ABS and TC, could be good to also add a brakingAssist indicator to the output which will help people keep track of aids being used. Maybe this could take up on of the "padding" bytes, or it could just share bits with one of the other TC/ABS settings i guess.

When traction control is off in the menu, the telemetry outputs it as 0.44999998807907. Im guessing that the game internally always has some level of TC so the cars are actually playable. Not sure if you want to do anything about this, or maybe just make a note of it. A value of 0.5 is TC medium and i think 1 was TC full. So you could say anything < 0.5 is considered off in the notes.

How often is the participant info going to be updated. Will it be updated as fast as the player data? If so then you could potentially consider removing the duplication of player fields from the main body where the players timing related info (and a couple of other things) is in the participants struct as well as in the main body of the struct. Useful if you need to free up more space in the structure so something else can be added, otherwise just a cleanliness thing if anything.

FYI the comments on the m_speed and m_pit_speed_limit fields in the structure are wrong, both indicate the value is in MPH but the value is actually in m/s (meters per second).

Am i correct in that the game can only currently be played in Time Trial mode? I wanted to test out the participant data, but cannot find anyway to start a game with other players in it.

One last question, is there a way to see telemetry in game yet? From memory on F1 2016 you could use the MFD to show brake temps, etc, will there be something like the available in F1 2017 too? i want to use it to validate the telemetry data for those things matches what the game is displaying.

I've just the traction control values with the handling team and they said this value is correct for the 2002 Ferrari as it has some in-built traction control. If you are seeing this with the modern cars or the 88 McLaren then there is probably a bug in there.

We'll get the IDs for the some classic teams and drivers released soon.

I've just the traction control values with the handling team and they said this value is correct for the 2002 Ferrari as it has some in-built traction control. If you are seeing this with the modern cars or the 88 McLaren then there is probably a bug in there.

We'll get the IDs for the some classic teams and drivers released soon.

Hi Hoo,

I definately wasnt using the 2002 Ferrari, but its possible i was using the 1992 williams, otherwise i was definately in a modern car. Do you need me to check for sure or are they able to check it out relatively easily?

@Kafumanto - this is a percentage of the maximum steering input. This is the raw input like the throttle and brake values. Converting it to an angle would need the final steering result outputted from the game, which is different to how we treat the other values.

@Kafumanto - this is a percentage of the maximum steering input. This is the raw input like the throttle and brake values. Converting it to an angle would need the final steering result outputted from the game, which is different to how we treat the other values.

Some question about struct CarUDPData, since my field of interest is the live coverage overlay

1) what is exactly this parameter?byte m_trackPosition; // track positions of vehicleis it similar to float m_car_position; // car race position ?If not... I can calculate the race car position using m_lapDistance & m_currentLapNum but ... but wow

2) calculating the delay between 2 drivers is not a problem using timers but there is one important info missing to determine the FINAL race car position: PENALTIES !! Time penalties greatly affect the final classification of the race in case of strict rules and it is typical to give this information to spectators during a live coverage.I don't think you will change now the total amount of bytes for each car but maybe you can send via UDP:

The data is sent as raw data in
the UDP packet, converted to a char array, with packing disabled. To decode
this into something usable it should be a case of casting the packet data back
to the UDPPacket struct (or another
structure with the same layout). The layout of the UDP data is as follows:

// Packet size – 1210 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

float m_xv; // Velocity in world space

float m_yv; // Velocity in world space

float m_zv; // Velocity in world space

float m_xr; // World space right direction

float m_yr; // World space right direction

float m_zr; // World space right direction

float m_xd; // World space forward direction

float m_yd; // World space forward direction

float m_zd; // World space forward direction

float m_susp_pos[4]; // Note: All wheel arrays have the order:

float m_susp_vel[4]; // RL, RR, FL, FR

float m_wheel_speed[4];

float m_throttle;

float m_steer;

float m_brake;

float m_clutch;

float m_gear;

float m_gforce_lat;

float m_gforce_lon;

float m_lap;

float m_engineRate;

float m_sli_pro_native_support; // SLI Pro support

float m_car_position; // car race position

float m_kers_level; // kers energy left

float m_kers_max_level; // kers maximum energy

float m_drs; // 0 = off, 1 = on

float m_traction_control; // 0 (off) - 2 (high)

float m_anti_lock_brakes; // 0 (off) - 1 (on)

float m_fuel_in_tank; // current fuel mass

float m_fuel_capacity; // fuel capacity

float m_in_pits; // 0 = none, 1 = pitting, 2 = in pit area

float m_sector; // 0 = sector1, 1 = sector2, 2 = sector3

float m_sector1_time; // time of sector1 (or 0)

float m_sector2_time; // time of sector2 (or 0)

float m_brakes_temp[4]; // brakes temperature (centigrade)

float m_tyres_pressure[4]; // tyres pressure PSI

float m_team_info; // team ID

float m_total_laps; // total number of laps in this race

float m_track_size; // track size meters

float m_last_lap_time; // last lap time

float m_max_rpm; // cars max RPM, at which point the rev limiter will kick in

Some question about struct CarUDPData, since my field of interest is the live coverage overlay

1) what is exactly this parameter?byte m_trackPosition; // track positions of vehicleis it similar to float m_car_position; // car race position ?If not... I can calculate the race car position using m_lapDistance & m_currentLapNum but ... but wow

2) calculating the delay between 2 drivers is not a problem using timers but there is one important info missing to determine the FINAL race car position: PENALTIES !! Time penalties greatly affect the final classification of the race in case of strict rules and it is typical to give this information to spectators during a live coverage.I don't think you will change now the total amount of bytes for each car but maybe you can send via UDP:

since best lap time is (not so important and) easily deductible from last lap time if following the race from the beginning.

I took m_trackPosition to mean race position, since its a byte. Car position on the track is m_WorldPosition[]

bestLapTime is important if the game allows players to join a multi player session while its in progress (eg qualifying or practice). It is then essential to have best lap time provided so anyone joining mid session can see the fastest times on the leaderboard.

having split time ahead provided by the telemetry means that players using slower telemetry tick update speeds can still have accurate split times, as calculating it yourself gets progressively less accurate as the tick rate is reduced.

There is still room in the cars struct to also include penalties, it may not need to be a float though as i presume its usually just +x seconds?

I haven't had a chance to test this yet, but im curious whether the telemetry will stop streaming the moment the player crosses the finish line at the end of a race, or whether it will continue to stream until all cars results are known. We really need it to go to the end so we can get accurate final results from the game.