Overview of GT7 Telemetry Software

  • Thread starter Thread starter snimat
  • 373 comments
  • 176,663 views
OTA update demo (staged rollout + worst-case hardware test)

Just a quick followup to the post above. Here is a full end-to-end demo of the OTA pipeline doing its job.



What's happening in the video
  • I upload a new software version through the hawkBit web frontend
  • I roll it out to the "dev" distribution channel only
  • The instrument cluster checks and sees the new version is available for its channel and pulls it down
  • It installs the update and reboots
  • It comes back up running the new version


Why the "dev channel" matters
This is the same staged-rollout pattern real vehicle fleets use. They don't push an update to every car at once; they rather push it to a canary group first, watch it behave and only then widen the rollout. The instrument-cluster's update channels work the same way: dev, and eventually a stable channel for everyone else, so a bad build never has to reach every device at the same time.

One detail worth pointing out
I ran this demo on a Raspberry Pi 5 with a VERY slow SD card on purpose. Wanted to see the update pipeline handle a sluggish I/O scenario rather than only showing the happy path on ideal hardware. It completed the download, install, and reboot without issue.

This is a proper update pipeline with targeted rollout groups, the same shape as what's used on actual vehicle software fleets, just running on a cheap board instead of a car's ECU cluster.
 

GT7 Track Identification from Telemetry – using Pit Box Coordinates as a Track Fingerprint​

I've been experimenting with ways to identify the current track in Gran Turismo 7 using only the UDP telemetry data, without relying on a Track ID.

I had an idea that might make this much simpler.

Every circuit has a pit lane, and when the car is in its pit box its world position can be read from telemetry as X/Y/Z coordinates.

My idea is to use the pit box position as a kind of track fingerprint.

For example, a database could contain something like:

Track A:
Pit position: X / Y / Z

Track B:
Pit position: X / Y / Z

Track C:
Pit position: X / Y / Z

When GT7 places the car in the pit box, the telemetry receiver could compare the current coordinates against this database and potentially identify the circuit immediately — without needing to drive a complete lap.

Even if different teams/cars are assigned slightly different pit boxes, I suspect that the group of possible pit positions for each circuit would still occupy a unique area in GT7's world coordinate system.

Another possibility would be to store additional information about the pit lane, such as:

  • X/Y/Z range of all pit boxes
  • orientation/heading of the car in the pit
  • pit lane direction
  • relative positions of several pit boxes
This could produce a stronger fingerprint than a single coordinate.

If two circuits happened to have similar pit coordinates, the identification could then be confirmed using telemetry collected after leaving the pits — for example the elevation profile (Y) relative to travelled distance, or a short section of the X/Z trajectory.

The goal would be to identify the track after only a few telemetry samples, ideally even before the car starts driving.

Has anyone experimented with this approach?

In particular, does anyone know whether the pit box X/Y/Z coordinates are stable between sessions and whether each circuit/layout uses its own coordinate space?

I'd be interested to hear from anyone who has collected GT7 position telemetry across multiple tracks.
 

GT7 Track Identification from Telemetry – using Pit Box Coordinates as a Track Fingerprint​

I've been experimenting with ways to identify the current track in Gran Turismo 7 using only the UDP telemetry data, without relying on a Track ID.

I had an idea that might make this much simpler.

Every circuit has a pit lane, and when the car is in its pit box its world position can be read from telemetry as X/Y/Z coordinates.

My idea is to use the pit box position as a kind of track fingerprint.

For example, a database could contain something like:

Track A:
Pit position: X / Y / Z

Track B:
Pit position: X / Y / Z

Track C:
Pit position: X / Y / Z

When GT7 places the car in the pit box, the telemetry receiver could compare the current coordinates against this database and potentially identify the circuit immediately — without needing to drive a complete lap.

Even if different teams/cars are assigned slightly different pit boxes, I suspect that the group of possible pit positions for each circuit would still occupy a unique area in GT7's world coordinate system.

Another possibility would be to store additional information about the pit lane, such as:

  • X/Y/Z range of all pit boxes
  • orientation/heading of the car in the pit
  • pit lane direction
  • relative positions of several pit boxes
This could produce a stronger fingerprint than a single coordinate.

If two circuits happened to have similar pit coordinates, the identification could then be confirmed using telemetry collected after leaving the pits — for example the elevation profile (Y) relative to travelled distance, or a short section of the X/Z trajectory.

The goal would be to identify the track after only a few telemetry samples, ideally even before the car starts driving.

Has anyone experimented with this approach?

In particular, does anyone know whether the pit box X/Y/Z coordinates are stable between sessions and whether each circuit/layout uses its own coordinate space?

I'd be interested to hear from anyone who has collected GT7 position telemetry across multiple tracks.
Unfortunately, the tracks do not inhabit unique global coordinates. I didn’t specifically test pit box locations, but I did compare start/finish positions across every layout. There is enough overlap that coordinates alone cannot uniquely identify the track.

The coordinates themselves are stable from session to session, so you can rely on that. The problem is uniqueness, not stability.

In practice, identification requires observing the car’s movement for a few seconds until its trajectory diverges from other candidate layouts.

Determining the exact layout can be even harder. Some layouts (for example, Spa) are identical on the racing surface and differ only in pit exit. If the car never enters the pits, telemetry alone provides no evidence to distinguish them.

Also worth noting: two GT7 layouts don’t have pit facilities at all, so a pit-based fingerprint can’t work universally.
 
Last edited:
Unfortunately, the tracks do not inhabit unique global coordinates. I didn’t specifically test pit box locations, but I did compare start/finish positions across every layout. There is enough overlap that coordinates alone cannot uniquely identify the track.

The coordinates themselves are stable from session to session, so you can rely on that. The problem is uniqueness, not stability.

In practice, identification requires observing the car’s movement for a few seconds until its trajectory diverges from other candidate layouts.

Determining the exact layout can be even harder. Some layouts (for example, Spa) are identical on the racing surface and differ only in pit exit. If the car never enters the pits, telemetry alone provides no evidence to distinguish them.

Also worth noting: two GT7 layouts don’t have pit facilities at all, so a pit-based fingerprint can’t work universally.
That makes sense. One thing I’m wondering about is whether adding yaw could reduce the number of collisions significantly.

Instead of comparing only X/Y/Z, the fingerprint could use:

X/Y/Z + yaw

and also limit the comparison to a smaller area around a known reference point, for example the starting grid or pit box position.

Even if two layouts have overlapping coordinates, their car orientation at that point may be different enough to separate them.

It would be interesting to test how many collisions remain after adding yaw and narrowing the coordinate tolerance/area.
 
That makes sense. One thing I’m wondering about is whether adding yaw could reduce the number of collisions significantly.

Instead of comparing only X/Y/Z, the fingerprint could use:

X/Y/Z + yaw

and also limit the comparison to a smaller area around a known reference point, for example the starting grid or pit box position.

Even if two layouts have overlapping coordinates, their car orientation at that point may be different enough to separate them.

It would be interesting to test how many collisions remain after adding yaw and narrowing the coordinate tolerance/area.
Yes, yaw may reduce the number of collisions substantially, especially if the goal is only to identify the circuit or venue.

The harder question is identifying the exact layout. Multiple layouts at the same venue can share the same pit area, grid, start line, direction, and much of the racing surface. In those cases, X/Y/Z plus yaw at a single reference point (well, within a small area around a point) may still be identical.

So I think this would be worth testing, but the result depends on what you need:
  • Venue identification: position plus yaw may be a strong fingerprint.
  • Exact layout identification: it may narrow the candidates, but a short trajectory or reaching a layout-specific section may still be required.
I may have assumed you meant exact layout identification. If you only need the venue, your approach is more promising.
 
Last edited:
What you are describing is basically what I use for EzioDash Pro, and it is most definitely possible to use this approach to identify tracks. But, it is a LOT of work, and it is far from 100%. And as Grey mentions, detecting the various layouts (Maggiore for example) adds yet another layer to it.
 
What you are describing is basically what I use for EzioDash Pro, and it is most definitely possible to use this approach to identify tracks. But, it is a LOT of work, and it is far from 100%. And as Grey mentions, detecting the various layouts (Maggiore for example) adds yet another layer to it.
I agree that yaw would probably help a lot with normal vs reverse layouts, since the car orientation should be very different.

The harder case is when two layouts share the same grid, coordinates and direction, and only diverge somewhere further around the circuit. In that case I don’t think XYZ + yaw can identify the exact layout while the car is stationary.

It may still be useful to identify the circuit immediately and narrow the result down to a small group of possible layouts, then resolve the exact layout only when the car reaches a distinguishing section.

I’ll do some testing and we’ll see how it works. Thank you everyone for the suggestions! :)
 
Last edited:
It may still be useful to identify the circuit immediately and narrow the result down to a small group of possible layouts, then resolve the exact layout only when the car reaches a distinguishing section.
Yep, exactly how I do it. Sort by elevation first, match on gates by pit exit or finish line, then check divergence by the candidates still in the running.
 
present I'm using EZIODASH Pro as main dash board. And I love the motivation from the box … 😇😊
additional a Android tablet with PRO Sim Dashboard on the side for more information with a little bit bigger letters for my old eyes 🤪

But I like to test @chrshdl solution also 😍
PI4 and a dashboard display 14,5" are on board … I'm curios

Thanks to all developers .. great job 👍🥰
Hi Taifun1800,

things have changed since my last reply. Revokyte (the instrument cluster) is now also available as a Desktop/PC app, so your 14.5" display would work, no Pi display needed. I have also set up a website with all the infos:


If you are still curious, I'd love to hear your thoughts. And if anyone here wants to test the Windows build specifically, that would be extra helpful ... I don't own a Windows machine :)
 
Last edited:
Has anyone made progress on the remaining 12 undecoded bytes in Packet C? I’ve seen the speculation that the last 4 relate to steering or yaw — is there any measured confirmation, or is it still open?
 
In my project I have the following definition for the tilde packet:

Code:
struct PacketTilde : public PacketB
{
    std::uint8_t throttleFiltered; // Filtered throttle output.
    std::uint8_t brakeFiltered;    // Filtered brake output.
    std::uint8_t UNKNOWNUINT81;    // Unknown byte preserved for binary layout compatibility.
    std::uint8_t UNKNOWNUINT82;    // Unknown byte preserved for binary layout compatibility.
    float torqueVectors[4];        // Per-wheel torque vectoring; positive is drive force, negative is braking/regeneration.
    float energyRecovery;          // Energy being recovered to the battery, for hybrid/EV behavior.
    float UNKNOWNFLOAT11;          // Unknown float preserved for binary layout compatibility.
};

UNKNOWNUINT82 appears to be tied to specific cars (e.g. it has a value of 1 for cars 3335, 3433, and 3607).

The three car codes I cited map to:

  • 3335 — McLaren Vision Gran Turismo (Gr.1)
  • 3433 — Ferrari FXX K ’14
  • 3607 — Porsche 963 ’24

I think this byte indicates (when it is 1) that the car has an energy recovery system, to go along with the 'energyRecovery' float within the same structure. I propose renaming 'UNKNOWNUINT82' to 'hasEnergyRecoverySystem'.

Can anyone else confirm my finding?
 
Last edited:
In my project I have the following definition for the tilde packet:

Code:
struct PacketTilde : public PacketB
{
    std::uint8_t throttleFiltered; // Filtered throttle output.
    std::uint8_t brakeFiltered;    // Filtered brake output.
    std::uint8_t UNKNOWNUINT81;    // Unknown byte preserved for binary layout compatibility.
    std::uint8_t UNKNOWNUINT82;    // Unknown byte preserved for binary layout compatibility.
    float torqueVectors[4];        // Per-wheel torque vectoring; positive is drive force, negative is braking/regeneration.
    float energyRecovery;          // Energy being recovered to the battery, for hybrid/EV behavior.
    float UNKNOWNFLOAT11;          // Unknown float preserved for binary layout compatibility.
};

UNKNOWNUINT82 appears to be tied to specific cars (e.g. it has a value of 1 for cars 3335, 3433, and 3607).

The three car codes I cited map to:

  • 3335 — McLaren Vision Gran Turismo (Gr.1)
  • 3433 — Ferrari FXX K ’14
  • 3607 — Porsche 963 ’24

I think this byte indicates (when it is 1) that the car has an energy recovery system, to go along with the 'energyRecovery' float within the same structure. I propose renaming 'UNKNOWNUINT82' to 'hasEnergyRecoverySystem'.

Can anyone else confirm my finding?
I can independently confirm and add some detail to this finding from my own
vehicle-by-vehicle testing.


UNKNOWNUINT82

I have only observed values of 0 and 1.

When this byte was 1, the energyRecovery float changed and appeared to
contain meaningful data. When it was 0, energyRecovery remained inactive or
unchanged.

However, not every hybrid or EV reports 1. I tested some electrified cars
that still reported 0, and their energyRecovery value did not change.

Because of this, I think hasEnergyRecoverySystem may be slightly misleading.
The byte may indicate whether energy-recovery telemetry is available for that
particular car, rather than whether the actual car has an energy recovery
system.

A temporary name such as energyRecoveryDataValid,
energyRecoveryTelemetryAvailable or reportsEnergyRecovery might therefore
be safer.


UNKNOWNUINT81

I have observed four values so far: 0, 2, 4 and 9.

My current observations are:

  • 0: no meaningful activity was observed in torqueVectors[4].
  • 2 or 4: torqueVectors[4] changed, and energyRecovery also appeared to contain active and valid data.
  • 9: torqueVectors[4] changed, but energyRecovery appeared to remain inactive or invalid.

I still do not know what distinguishes 2 from 4.

This byte may be an enum or bitfield describing the type or configuration of
an electrified drivetrain or torque-vectoring system, rather than a simple
true/false flag.

So far, I have not found a non-electrified car that produces meaningful
torqueVectors[4] data, although I have not tested every vehicle.


UNKNOWNFLOAT11

This final float does not appear to be padding.

It changes actively while the vehicle is moving. When the vehicle is
completely stationary, it settles very close to zero and fluctuates slightly
between small negative and positive values.

It therefore appears to contain some kind of vehicle-motion or dynamics
information, although I have not yet identified the exact quantity, axis or
unit.
 
I can independently confirm and add some detail to this finding from my own
vehicle-by-vehicle testing.


UNKNOWNUINT82

I have only observed values of 0 and 1.

When this byte was 1, the energyRecovery float changed and appeared to
contain meaningful data. When it was 0, energyRecovery remained inactive or
unchanged.

However, not every hybrid or EV reports 1. I tested some electrified cars
that still reported 0, and their energyRecovery value did not change.

Because of this, I think hasEnergyRecoverySystem may be slightly misleading.
The byte may indicate whether energy-recovery telemetry is available for that
particular car, rather than whether the actual car has an energy recovery
system.

A temporary name such as energyRecoveryDataValid,
energyRecoveryTelemetryAvailable or reportsEnergyRecovery might therefore
be safer.


UNKNOWNUINT81

I have observed four values so far: 0, 2, 4 and 9.

My current observations are:

  • 0: no meaningful activity was observed in torqueVectors[4].
  • 2 or 4: torqueVectors[4] changed, and energyRecovery also appeared to contain active and valid data.
  • 9: torqueVectors[4] changed, but energyRecovery appeared to remain inactive or invalid.

I still do not know what distinguishes 2 from 4.

This byte may be an enum or bitfield describing the type or configuration of
an electrified drivetrain or torque-vectoring system, rather than a simple
true/false flag.

So far, I have not found a non-electrified car that produces meaningful
torqueVectors[4] data, although I have not tested every vehicle.


UNKNOWNFLOAT11

This final float does not appear to be padding.

It changes actively while the vehicle is moving. When the vehicle is
completely stationary, it settles very close to zero and fluctuates slightly
between small negative and positive values.

It therefore appears to contain some kind of vehicle-motion or dynamics
information, although I have not yet identified the exact quantity, axis or
unit.
This is great information!

I agree with you about UNKNOWNUINT82. hasEnergyRecoverySystem probably claims more than the data actually tells us. If you’ve found electrified cars where the byte is 0 and energyRecovery remains inactive, then this looks more like a statement about the telemetry being reported than the physical capabilities of the car.

Of the names you suggested, I think I like energyRecoveryTelemetryAvailable. It’s a little verbose, but it’s also difficult to misinterpret.

Your UNKNOWNUINT81 results are particularly interesting. I’ve only observed 0 in my own captures, so I had basically written that byte off for the time being.

The values you’ve found – 0, 2, 4, and 9 – also make me wonder whether it could be a bitmask rather than an enum. In binary, those nonzero values are:

2 = 0010
4 = 0100
9 = 1001

That’s obviously nowhere near enough evidence to conclude that it is a bitmask, but those values are suspiciously bitmask-like. If it is, the behavior you’re seeing with torqueVectors and energyRecovery might eventually let us tease apart what the individual bits represent.

I’ve done some work on UNKNOWNFLOAT11 as well. I agree that it is definitely active telemetry rather than padding. In my captures it correlates very strongly with boost and throttle: about +0.921 with boost, +0.896 with filtered throttle, and +0.872 with raw throttle. I’ve also seen a weaker but still substantial correlation with longitudinal acceleration, roughly +0.65 to +0.72 depending on the capture. Based on that, my current working hypothesis is that it represents something related to delivered engine torque/load. I haven’t identified the exact quantity or units, though, so I’m definitely not ready to put a real name on it yet. Your observation that it settles close to zero while completely stationary seems compatible with that interpretation.
 
Back