Crates.io | iracing |
lib.rs | iracing |
version | 0.4.1 |
source | src |
created_at | 2020-03-10 21:21:02.521127 |
updated_at | 2020-12-24 22:52:37.200205 |
description | Rust interface for Live Telemetry, Session Data, and Setup Files for iRacing |
homepage | |
repository | https://github.com/LeoAdamek/iracing.rs |
max_upload_size | |
id | 217389 |
size | 468,381 |
Live telemetry and session data interface for Rust.
See further examples in /examples
extern crate iracing;
use iracing::Connection;
use iracing::telemetry::TelemetryError;
pub fn main() {
// Open the iRacing Telemetry data
let conn = Connection::new().expect("Unable to open telemetry. Is iRacing running?");
// Get a blocking telemetry client
let bc = Connection::blocking().expect("Unable to start telemetry reader");
loop {
// bc.get() will block until new telemetry data is available.
let sample = match bc.get() {
Ok(sample) => sample,
Err(TelemetryError::TIMEOUT(ms)) => panic!("Telemetry timed out after {}ms", ms);
Err(error) => panic!("Telemetry Error: {:?}", error);
}
}
}
iRacing provides very little documentation on how the telemetry data is exported, so here's my version of it.
iRacing exports telemetry to a non-persisted memory-mapped file.
This allows iRacing to provide telemetry data with a high update rate which
can be read by multiple reading applications.
The shared memory space is always called Local\\IRSDKMemMapFileName
.
This memory contains four main areas:
A top-level header which describes the content of the memory space including:
An ISO-8859-1 encoded YAML string containing semi-static session information such as the name and layout of the track, the cars being driven and the users driving those cars.
A secondary header which describes the data available in the telemetry buffers
Up to 4 telemetry data buffers
The simulator cycles through up to 4 telemetry data buffers when writing telemetry and updates the top-level header to indicate when each buffer was last updated and where it is located. All buffers share the same structure, the number of values available is fixed per-session.
The session data can be read as a string given the location and size indicated by the top-level header and parsed as YAML to get the full details of the session. The structure of the YAML document is provided in the IRSDK documentation.
The telemetry data available is variable and depends primarily on the player's car. The top-level header denotes how many telemetry values are available and a pointer to the start of an array of structures which describe these contents. The structure is as follows:
typedef struct iracing_telem_var_header {
int value_type /* Enum of value type */
int offset /* Offset from start of telemetry buffer where variable is stored */
int count /* A count of values for this variable */
char [3]pad /* Padding */
char [32]name /* Varaible name */
char [64]desc /* Variable description */
char [32]units /* Variable units */
}
If the top-level header indicates there are 548 variables,
then the the variables header will be an array of 548 items (iracing_telem_var_header[548]
).
This header can then used as a look-up-table to find specific telemetry variables
within the telemetry buffer.
For example, given the following variable header:
{
.value_type = 1, /* float */
.offset = 0x4F82,
.count = 6,
.pad = [0,0,0],
.name = "DampDeflectLR",
.desc = "Damper Deflection (Left-Rear)",
.units = "mm"
};
We know that the variable "DampDeflectLR" exists 0x4F82
bytes from the start
of the telemetry buffer, the values are floats, of 4-bytes each and there are 6
values.
Knowing this we will need to read 24 bytes starting 0x4F82
bytes from the start
of the telemetry buffer to 0x4F93
which will give us an array of 6 float
s
A C implementation would look like this:
float* suspension_deflect = (float*)calloc(6, sizeof(float));
size_t suspection_deflect_loc = 0x4F82;
memcpy(suspension_deflect, telem_buffer_start + suspension_deflect_loc, 6 * sizeof(float));