Skip to main content
The Telemetry class provides access to multi-channel time series telemetry data from Formula 1 cars.

Telemetry

DataFrame-like object containing multi-channel telemetry data. Constructor:
session
Session | None
default:"None"
Instance of Session class (required for full functionality)
driver
str | None
default:"None"
Driver number as string (required for full functionality)
drop_unknown_channels
bool
default:"False"
Remove all unknown data channels on initialization

Available Channels

Car Data Channels

  • Speed (float64): Car speed in km/h
  • RPM (float64): Engine RPM
  • nGear (int): Current gear number
  • Throttle (float64): Throttle pedal position (0-100%). Note: 104 sometimes indicates error/unavailable data.
  • Brake (bool): Whether brakes are applied
  • DRS (int): DRS status indicator

Position Data Channels

  • X (float64): X coordinate position (1/10 meter)
  • Y (float64): Y coordinate position (1/10 meter)
  • Z (float64): Z coordinate position (1/10 meter)
  • Status (str): Track status flag - ‘OnTrack’ or ‘OffTrack’

Time Channels

  • Time (timedelta64[ns]): Time elapsed since start of data slice (0 at start)
  • SessionTime (timedelta64[ns]): Time elapsed since session start
  • Date (datetime64[ns]): Full timestamp for this sample

Metadata Channels

  • Source (str): How this sample was created:
    • ‘car’: from original car data API
    • ‘pos’: from original position data API
    • ‘interpolated’: artificially created/interpolated sample

Computed Channels

These channels can be added using the corresponding add_*() methods:
  • Distance (float64): Distance driven since first sample (meters)
  • DifferentialDistance (float64): Distance between samples (meters)
  • RelativeDistance (float64): Relative distance (0.0 to 1.0)
  • DriverAhead (str): Driver number of car ahead
  • DistanceToDriverAhead (float64): Distance to car ahead (meters)
  • TrackStatus (int): Track status number

Class Attributes

TELEMETRY_FREQUENCY

type
str | int
Defines the frequency used when resampling telemetry data. Either the string ‘original’ (default) or an integer to specify frequency in Hz.

Slicing Methods

slice_by_mask()

Slice telemetry using a boolean array as a mask.
mask
list | pd.Series | np.ndarray
required
Array of boolean values with the same length as self
pad
int
default:"0"
Number of samples used for padding the sliced data
pad_side
str
default:"'both'"
Where to pad: ‘both’, ‘before’, or ‘after’
return
Telemetry
Sliced Telemetry object

slice_by_lap()

Slice telemetry to include only data from specific lap(s).
ref_laps
Lap | Laps
required
The lap or laps to slice by
pad
int
default:"0"
Number of samples for padding
pad_side
str
default:"'both'"
Where to pad: ‘both’, ‘before’, or ‘after’
interpolate_edges
bool
default:"False"
Add interpolated samples at beginning and end to exactly match time window
return
Telemetry
Sliced Telemetry object
Requires ‘SessionTime’ column to be present.

slice_by_time()

Slice telemetry to include only data in a specific time frame.
start_time
pd.Timedelta
required
Start of the time window
end_time
pd.Timedelta
required
End of the time window
pad
int
default:"0"
Number of samples for padding
pad_side
str
default:"'both'"
Where to pad: ‘both’, ‘before’, or ‘after’
interpolate_edges
bool
default:"False"
Add interpolated samples at edges
return
Telemetry
Sliced Telemetry object

Data Manipulation Methods

merge_channels()

Merge telemetry objects containing different channels.
other
Telemetry | pd.DataFrame
required
Telemetry object to merge with self
frequency
int | Literal['original'] | None
default:"None"
Optional frequency override. Either ‘original’ or integer for Hz.
return
Telemetry
Merged Telemetry object with all channels
The two objects don’t need a common time base. Data will be merged, optionally resampled, and missing values interpolated.

resample_channels()

Resample telemetry data to a different frequency.
rule
str | None
default:"None"
Resampling rule for pandas.Series.resample (e.g., ‘10ms’, ‘100ms’)
new_date_ref
pd.Series | None
default:"None"
Alternative: provide a custom Series of new date reference timestamps
**kwargs
Any
Additional parameters passed to pandas.Series.resample
return
Telemetry
Resampled Telemetry object
Specify either ‘rule’ or ‘new_date_ref’, not both.

fill_missing()

Calculate missing values using interpolation.
return
Telemetry
Telemetry object with interpolated values
Different interpolation methods are used depending on the channel type (linear for continuous values like Speed, forward-fill for discrete values like nGear).

Adding Computed Channels

add_distance()

Add ‘Distance’ column containing cumulative distance driven.
drop_existing
bool
default:"True"
Drop and recalculate if column already exists
return
Telemetry
Self with new ‘Distance’ column
Distance is calculated by integration. Integration error accumulates over long distances. Apply only to single laps or few laps at a time.

add_differential_distance()

Add ‘DifferentialDistance’ column with distance between samples.
drop_existing
bool
default:"True"
Drop and recalculate if column already exists
return
Telemetry
Self with new ‘DifferentialDistance’ column

add_relative_distance()

Add ‘RelativeDistance’ column (0.0 at start, 1.0 at end).
drop_existing
bool
default:"True"
Drop and recalculate if column already exists
return
Telemetry
Self with new ‘RelativeDistance’ column

add_driver_ahead()

Add ‘DriverAhead’ and ‘DistanceToDriverAhead’ columns.
drop_existing
bool
default:"True"
Drop and recalculate if columns already exist
return
Telemetry
Self with new columns
Like add_distance(), this should only be applied to single laps or few laps at a time. Cars in the pit lane are not excluded.

add_track_status()

Add ‘TrackStatus’ column with track status for each sample.
drop_existing
bool
default:"True"
Drop and recalculate if column already exists
return
Telemetry
Self with new ‘TrackStatus’ column

Calculation Methods

calculate_differential_distance()

Calculate distance between samples.
return
pd.Series
Series with differential distance values in meters

integrate_distance()

Calculate cumulative distance from first sample.
return
pd.Series
Series with distance values in meters

calculate_driver_ahead()

Calculate driver ahead and distance to driver ahead.
return_reference
bool
default:"False"
Additionally return the reference telemetry slice used for calculation
return
tuple
(driver_ahead: np.ndarray, distance: np.ndarray, [optional: reference_telemetry])

Class Methods

register_new_channel()

Register a custom telemetry channel for automatic interpolation.
name
str
required
Channel/column name
signal_type
str
required
One of ‘continuous’, ‘discrete’, or ‘excluded’
interpolation_method
str | None
default:"None"
Interpolation method (required for continuous signals). See pandas.Series.interpolate for options.
Example:
from fastf1.core import Telemetry

# Register custom channel
Telemetry.register_new_channel(
    name='CustomSpeed',
    signal_type='continuous',
    interpolation_method='linear'
)

Complete Usage Example

import fastf1
import matplotlib.pyplot as plt

# Load session
session = fastf1.get_session(2023, 'Monaco', 'Race')
session.load()

# Get fastest lap
laps = session.laps.pick_drivers('VER')
fastest = laps.pick_fastest()

# Get telemetry
tel = fastest.get_telemetry()

# Add computed channels
tel = tel.add_distance()
tel = tel.add_relative_distance()
tel = tel.add_driver_ahead()

# Basic telemetry plot
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 8), sharex=True)

# Speed
ax1.plot(tel['Distance'], tel['Speed'])
ax1.set_ylabel('Speed (km/h)')
ax1.set_title('Verstappen - Fastest Lap Telemetry')

# Throttle and Brake
ax2.plot(tel['Distance'], tel['Throttle'], label='Throttle')
ax2.plot(tel['Distance'], tel['Brake'] * 100, label='Brake')
ax2.set_ylabel('%')
ax2.legend()

# Gear
ax3.plot(tel['Distance'], tel['nGear'])
ax3.set_xlabel('Distance (m)')
ax3.set_ylabel('Gear')

plt.tight_layout()
plt.show()

# Slice telemetry for specific section
t_start = fastest['LapStartTime'] + pd.Timedelta(seconds=10)
t_end = fastest['LapStartTime'] + pd.Timedelta(seconds=20)
tel_slice = tel.slice_by_time(t_start, t_end)

print(f"Speed range: {tel_slice['Speed'].min():.1f} - {tel_slice['Speed'].max():.1f} km/h")

# Compare two laps
ver_lap = laps.pick_fastest()
ham_laps = session.laps.pick_drivers('HAM')
ham_lap = ham_laps.pick_fastest()

ver_tel = ver_lap.get_telemetry().add_distance()
ham_tel = ham_lap.get_telemetry().add_distance()

# Plot comparison
fig, ax = plt.subplots()
ax.plot(ver_tel['Distance'], ver_tel['Speed'], label='VER')
ax.plot(ham_tel['Distance'], ham_tel['Speed'], label='HAM')
ax.set_xlabel('Distance (m)')
ax.set_ylabel('Speed (km/h)')
ax.legend()
ax.set_title('Speed Comparison - Fastest Laps')
plt.show()

Build docs developers (and LLMs) love