Skip to main content

Get Grand Turismo telemetry data from the PlayStation console

Project description

GranTurismo

This package wraps the Gran Turismo 7's unofficial telemetry API. By providing this module with you're PlayStation's IP address (as found in the menu) you will be able to retrieve packets containing telemetry data.

Usage

The main function is the Listener, which is a closing object. You can use a with Listener(ip_address) as ... clause to open and close the listener. The Listener will spin up a background thread to maintain a heartbeat connection with the PlayStation, so it's important to always close the object.

Quickstart example

Grab a single packet from Gran Turismo and print it

from granturismo.intake import Listener
import sys

if __name__ == '__main__':
  ip_address = sys.argv[1] # IP address to the PlayStation
  
  # Create a new Listener session and print the first packet that Gran Turismo sends.
  with Listener(ip_address) as listener:
    print(listener.get())

Streaming data example

Stream all incoming data from Gran Turismo and print it to the terminal

from granturismo.intake import Listener
from granturismo.model import Wheels
import datetime as dt
import time, sys
import curses

stdscr = curses.initscr()

# This function is used to rewrite multiple lines on the terminal
def report_suspension(wheels: Wheels) -> None:
  curr_time = dt.datetime.fromtimestamp(time.time()).isoformat()
  stdscr.addstr(0, 0, f'[{curr_time}] Suspension Height')
  stdscr.addstr(1, 0, f'\t{wheels.front_left.suspension_height:.3f}    {wheels.front_right.suspension_height:.3f}')
  stdscr.addstr(2, 0, f'\t{wheels.rear_left.suspension_height:.3f}    {wheels.rear_right.suspension_height:.3f}')
  stdscr.refresh()

if __name__ == '__main__':
  ip_address = sys.argv[1]

  # To use the Listener session without a `with` clause, you'll need to call the `.start()` function. 
  listener = Listener(ip_address)
  listener.start()

  try:
    while True:
      # get the latest packet from PlayStation
      packet = listener.get()

      # If the game isn't paused or in a loading state, we'll update the terminal with the latest suspension info.
      if not packet.flags.loading_or_processing and not packet.flags.paused:
        report_suspension(packet.wheels)
  finally:
    # If you don't use a `with` clause, then you'll need to close the session afterwords. Session will also successfully close with CTRL+C
    curses.echo()
    curses.nocbreak()
    curses.endwin()
    listener.close()

Data

Because this is an unofficial API, the range expected min/max of each value is still unknown. As more effort is put into understanding this API, better information will be available. For now, here is what we know.

  • int: packet_id
  • int: car_id cars with more than 8 gears will overwrite this value with a gear ratio
  • Optional(int): lap_count None if not in race
  • Optional(int): laps_in_race None if not in race
  • Optional(int): best_lap_time In milliseconds. None if not in race, or no lap complete.
  • Optional(int): last_lap_time In milliseconds. None if no lap completed
  • Vector: position
    • float: x
    • float: y
    • float: z
  • Vector: velocity in meters per second
    • float: x
    • float: y
    • float: z
  • Vector: angular_velocity radians per second
    • float: x
    • float: y
    • float: z
  • Rotation: rotation Seems to be the real part of a unit quaternion that gives the rotation of the car relative to the track coordinate system
    • float: pitch
    • float: yaw
    • float: roll
  • Vector: road_plane
    • float: x
    • float: y
    • float: z
  • float: road_distance: Should match the body_height when car is on the ground
  • Wheels: wheels
    • Wheel: front_left
      • float: suspension_height: between 0-1. Lower number equates to uncompressed, higher number to a more compressed suspension
      • float: radius: Radius of the tire in meters
      • float: rps: Rotations per second
      • float: ground_speed: The speed the tire is traveling on the ground in meters per second.
      • float: temperature: The surface temperature of the tire in celsius
    • Wheel: front_right
      • float: suspension_height: between 0-1. Lower number equates to uncompressed, higher number to a more compressed suspension
      • float: radius: Radius of the tire in meters
      • float: rps: Rotations per second
      • float: ground_speed: The speed the tire is traveling on the ground in meters per second.
      • float: temperature: The surface temperature of the tire in celsius
    • Wheel: rear_left
      • float: suspension_height: between 0-1. Lower number equates to uncompressed, higher number to a more compressed suspension
      • float: radius: Radius of the tire in meters
      • float: rps: Rotations per second
      • float: ground_speed: The speed the tire is traveling on the ground in meters per second.
      • float: temperature: The surface temperature of the tire in celsius
    • Wheel: rear_right
      • float: suspension_height: between 0-1. Lower number equates to uncompressed, higher number to a more compressed suspension
      • float: radius: Radius of the tire in meters
      • float: rps: Rotations per second
      • float: ground_speed: The speed the tire is traveling on the ground in meters per second.
      • float: temperature: The surface temperature of the tire in celsius
  • Flags: flags
    • bool: in_race
    • bool: paused
    • bool: loading_or_processing
    • bool: in_gear 0 when shifting or out of gear, standing
    • bool: has_turbo
    • bool: rev_limiter_alert_active
    • bool: hand_brake_active
    • bool: lights_active
    • bool: lights_high_beams_active
    • bool: lights_low_beams_active
    • bool: asm_active
    • bool: tcs_active
    • bool: unused1 always False
    • bool: unused2 always False
    • bool: unused3 always False
    • bool: unused4 always False
  • float: orientation
  • float: body_height in meters
  • float: engine_rpm 0-?
  • float: gas_level 0-100
  • float: gas_capacity 100 for gas cars, 5 for karts, 0 for electric
  • float: car_speed in meters per second
  • float: turbo_boost this value - 1 gives the Turbo Boost display
  • float: oil_pressure in bars?
  • float: oil_temperature in celsius. Seems to always be 85.0
  • float: water_temperature in celsius. Seems to always be 110.0
  • int: time_of_day millisecond timestamp, time of day indicates race start time of day, affected by Variable Time Speed Ratio, useless for timing when time speed ratio is not 1
  • Optional(int): start_position only available before race starts, otherwise None
  • Optional(int): cars_in_race only available before race starts, otherwise None
  • Bounds: rpm_alert
    • float: min 0-?
    • float: max 0-?
  • int: car_max_speed in meters per second
  • float: transmission_max_speed corresponds to the Top Speed setting of a customizable gear box in the car settings, given as gear ratio
  • int: throttle between 0-255
  • int: brake between 0-255
  • float: clutch between 0-1. This seems to correlate with the clutch peddle
  • float: clutch_engagement between 0-1
  • float: clutch_gearbox_rpm
  • Optional(int): current_gear 0-4: current gear, 0 is reverse, None is neutral
  • Optional(int): suggested_gear. None if there's no suggested gear
  • List(float): gear_ratios 1st - Nth gear.
  • int: unused_0x93 always 0
  • int: unused_0xD4 always 0

References

Nenkai is the original discoverer of this API and how to decrypt and communicate with it, as well as a significant amount of research into each value.

tarnheld for their work in identifying data values/ranges.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

granturismo-0.0.9.tar.gz (14.9 kB view details)

Uploaded Source

Built Distributions

granturismo-0.0.9-py3.9.egg (31.7 kB view details)

Uploaded Source

granturismo-0.0.9-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file granturismo-0.0.9.tar.gz.

File metadata

  • Download URL: granturismo-0.0.9.tar.gz
  • Upload date:
  • Size: 14.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.14

File hashes

Hashes for granturismo-0.0.9.tar.gz
Algorithm Hash digest
SHA256 579b7c7eb857e26a4cf216301a1b1c26fd503b36c5a9d0e3a676b2505c443deb
MD5 6bf49a6b44307d8976ab3043557cd7ce
BLAKE2b-256 7141dccbb22d0507f780d0a970419f78918d4f492ff2720b071826e262347645

See more details on using hashes here.

File details

Details for the file granturismo-0.0.9-py3.9.egg.

File metadata

  • Download URL: granturismo-0.0.9-py3.9.egg
  • Upload date:
  • Size: 31.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.14

File hashes

Hashes for granturismo-0.0.9-py3.9.egg
Algorithm Hash digest
SHA256 d0ffa1f91f1ba18e343957f83777f0e959acc16313b455125d040d2dc52c83c6
MD5 4608c26d87a108134d0033a7784d13fb
BLAKE2b-256 8a14a2fa6c92dc98506c16d5ffeed12e843949726268a4e774e57f3923eed0f3

See more details on using hashes here.

File details

Details for the file granturismo-0.0.9-py3-none-any.whl.

File metadata

  • Download URL: granturismo-0.0.9-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.14

File hashes

Hashes for granturismo-0.0.9-py3-none-any.whl
Algorithm Hash digest
SHA256 f146509d30d199095da6e8573b97998026038407a0638f53c7b5d636fa435031
MD5 29575133233519a63b50635c525f74b2
BLAKE2b-256 bf02b492dfabfd246740b5d404b0e0a63bf3db3f8a8d0774450a5e90cc05ba81

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page