Fix and verify telemetry reading

This commit is contained in:
hodasemi 2023-01-12 23:16:24 +01:00
parent dc729b3f10
commit 8e7600b3d8
3 changed files with 165 additions and 25 deletions

View file

@ -172,10 +172,10 @@ struct TelemWheelV01
struct TelemInfoV01
{
// Time
long mID; // slot ID (note that it can be re-used in multiplayer after someone leaves)
int mID; // slot ID (note that it can be re-used in multiplayer after someone leaves)
double mDeltaTime; // time since last update (seconds)
double mElapsedTime; // game session time
long mLapNumber; // current lap number
int mLapNumber; // current lap number
double mLapStartET; // time this lap was started
char mVehicleName[64]; // current vehicle name
char mTrackName[64]; // current track name
@ -192,7 +192,7 @@ struct TelemInfoV01
TelemVect3 mLocalRotAccel; // rotational acceleration (radians/sec^2) in local vehicle coordinates
// Vehicle status
long mGear; // -1=reverse, 0=neutral, 1+=forward gears
int mGear; // -1=reverse, 0=neutral, 1+=forward gears
double mEngineRPM; // engine RPM
double mEngineWaterTemp; // Celsius
double mEngineOilTemp; // Celsius
@ -227,9 +227,9 @@ struct TelemInfoV01
double mFuel; // amount of fuel (liters)
double mEngineMaxRPM; // rev limit
unsigned char mScheduledStops; // number of scheduled pitstops
bool mOverheating; // whether overheating icon is shown
bool mDetached; // whether any parts (besides wheels) have been detached
bool mHeadlights; // whether headlights are on
char mOverheating; // whether overheating icon is shown
char mDetached; // whether any parts (besides wheels) have been detached
char mHeadlights; // whether headlights are on
unsigned char mDentSeverity[8];// dent severity at 8 locations around the car (0=none, 1=some, 2=more)
double mLastImpactET; // time of last impact
double mLastImpactMagnitude; // magnitude of last impact
@ -237,7 +237,7 @@ struct TelemInfoV01
// Expanded
double mEngineTorque; // current engine torque (including additive torque) (used to be mEngineTq, but there's little reason to abbreviate it)
long mCurrentSector; // the current sector (zero-based) with the pitlane stored in the sign bit (example: entering pits from third sector gives 0x80000002)
int mCurrentSector; // the current sector (zero-based) with the pitlane stored in the sign bit (example: entering pits from third sector gives 0x80000002)
unsigned char mSpeedLimiter; // whether speed limiter is on
unsigned char mMaxGears; // maximum forward gears
unsigned char mFrontTireCompoundIndex; // index within brand

View file

@ -1,4 +1,3 @@
use anyhow::Error as AnyError;
use std::mem;
use crate::rfactor_structs::*;
@ -21,25 +20,23 @@ pub struct rF2Telemetry {
pub bytes_update_hint: i32,
pub num_vehicles: i32,
pub vehicle_telemetry: [TelemInfoV01; MAX_MAPPED_VEHICLES],
pub vehicle_telemetry: [rF2VehicleTelemetry; MAX_MAPPED_VEHICLES],
}
impl rF2Telemetry {
pub const SIZE: usize = mem::size_of::<Self>();
pub fn vehicles(&self) -> &[TelemInfoV01] {
pub fn vehicles(&self) -> &[rF2VehicleTelemetry] {
&self.vehicle_telemetry[0..self.num_vehicles as usize]
}
}
impl TryFrom<&[u8]> for rF2Telemetry {
type Error = AnyError;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
impl From<&[u8]> for rF2Telemetry {
fn from(value: &[u8]) -> Self {
debug_assert!(value.len() == Self::SIZE);
let fixed_size: [u8; Self::SIZE] = value.try_into().unwrap();
Ok(unsafe { mem::transmute(fixed_size) })
unsafe { mem::transmute(fixed_size) }
}
}
@ -58,13 +55,157 @@ impl rF2Scoring {
pub const SIZE: usize = mem::size_of::<Self>();
}
impl TryFrom<&[u8]> for rF2Scoring {
type Error = AnyError;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
impl From<&[u8]> for rF2Scoring {
fn from(value: &[u8]) -> Self {
debug_assert!(value.len() == Self::SIZE);
let fixed_size: [u8; Self::SIZE] = value.try_into().unwrap();
Ok(unsafe { mem::transmute(fixed_size) })
unsafe { mem::transmute(fixed_size) }
}
}
#[repr(C, packed(4))]
#[derive(Debug, Copy, Clone)]
pub struct rF2Vec3 {
pub x: f64,
pub y: f64,
pub z: f64,
}
#[repr(C, packed(4))]
#[derive(Debug, Copy, Clone)]
pub struct rF2VehicleTelemetry {
// Time
pub id: i32,
pub delta_time: f64,
pub elapsed_time: f64,
pub lap_number: i32,
pub lap_start_et: f64,
pub vehicle_name: [u8; 64],
pub track_name: [u8; 64],
// Position and derivatives
pub position: rF2Vec3,
pub local_velocity: rF2Vec3,
pub local_acceleration: rF2Vec3,
// Orientation and derivatives
pub orientation: [rF2Vec3; 3],
pub local_rotation: rF2Vec3,
pub local_rotational_acceleration: rF2Vec3,
// Vehicle status
pub gear: i32,
pub engine_rpm: f64,
pub engine_water_temp: f64,
pub engine_oil_temp: f64,
pub clutch_rpm: f64,
// Driver input
pub unfiltered_throttle: f64,
pub unfiltered_brake: f64,
pub unfiltered_steering: f64,
pub unfiltered_clutch: f64,
// Filtered input (various adjustments for rev or speed limiting, TC, ABS?, speed sensitive steering, clutch work for semi-automatic shifting, etc.)
pub filtered_throttle: f64,
pub filtered_brake: f64,
pub filtered_steering: f64,
pub filtered_clutch: f64,
// Misc
pub steering_shaft_torque: f64,
pub front_3rd_deflection: f64,
pub rear_3rd_deflection: f64,
// Aerodynamics
pub front_wing_height: f64,
pub front_ride_height: f64,
pub rear_ride_height: f64,
pub drag: f64,
pub front_downforce: f64,
pub rear_downforce: f64,
// State/damage info
pub fuel: f64,
pub engine_max_rpm: f64,
pub scheduled_stops: u8,
pub overheating: u8,
pub detached: u8,
pub headlights: u8,
pub dent_severity: [u8; 8],
pub last_impact_et: f64,
pub last_impact_magnitude: f64,
pub last_impact_position: rF2Vec3,
// Expanded
pub engine_torque: f64,
pub current_sector: i32,
pub speed_limiter: u8,
pub max_gears: u8,
pub front_tire_compound_index: u8,
pub rear_tire_compound_index: u8,
pub fuel_capacity: f64,
pub front_flap_activated: u8,
pub read_flap_activated: u8,
pub rear_flap_legal_status: u8,
pub ignition_start: u8,
pub front_tire_compound_name: [u8; 18],
pub rear_tire_compound_name: [u8; 18],
pub speed_limier_available: u8,
pub anti_stall_activated: u8,
unused: [u8; 2],
pub visual_steering_wheel_range: f32,
pub rear_brake_bias: f64,
pub turbo_boot_pressure: f64,
pub physics_to_graphics_offset: [f32; 3],
pub physical_steering_wheel_range: f32,
// Future use
expansion: [u8; 152],
// keeping this at the end of the structure to make it easier to replace in future versions
pub wheels: [rF2Wheel; 4],
}
#[repr(C, packed(4))]
#[derive(Debug, Copy, Clone)]
pub struct rF2Wheel {
pub suspension_deflection: f64,
pub ride_height: f64,
pub susp_force: f64,
pub brake_temp: f64,
pub brake_pressure: f64,
pub rotation: f64,
pub lateral_patch_vel: f64,
pub longitudinal_patch_vel: f64,
pub lateral_ground_vel: f64,
pub longitudinal_ground_vel: f64,
pub camber: f64,
pub lateral_force: f64,
pub longitudinal_force: f64,
pub tire_load: f64,
pub grip_fract: f64,
pub pressure: f64,
pub temperature: [f64; 3],
pub wear: f64,
pub terrain_name: [u8; 16usize],
pub surface_type: u8,
pub flat: u8,
pub detached: u8,
pub static_undeflected_radius: u8,
pub vertical_tire_deflection: f64,
pub wheel_y_location: f64,
pub toe: f64,
pub tire_carcass_temperature: f64,
pub tire_inner_layer_temperature: [f64; 3],
expansion: [::std::os::raw::c_uchar; 24usize],
}

View file

@ -1,4 +1,4 @@
mod additional_rfactor;
pub mod additional_rfactor;
#[allow(warnings)]
mod rfactor_structs;
@ -7,7 +7,6 @@ use std::{fs::File, path::Path};
use additional_rfactor::*;
use anyhow::Result;
use memmap2::Mmap;
use rfactor_structs::TelemInfoV01;
const RFACTOR_SHM_FILE: &str = "/dev/shm";
@ -27,10 +26,10 @@ impl TelemetryReader {
})
}
pub fn query_telemetry(&self) -> Result<Vec<TelemInfoV01>> {
let telemetry = rF2Telemetry::try_from(&self.shm[0..rF2Telemetry::SIZE])?;
pub fn query_telemetry(&self) -> Vec<rF2VehicleTelemetry> {
let telemetry = rF2Telemetry::from(&self.shm[0..rF2Telemetry::SIZE]);
let vehicles = telemetry.vehicles();
Ok(vehicles.to_vec())
vehicles.to_vec()
}
}