From 8e7600b3d86129c65d8a3a8e6ffc8e20d4af0d0b Mon Sep 17 00:00:00 2001 From: hodasemi Date: Thu, 12 Jan 2023 23:16:24 +0100 Subject: [PATCH] Fix and verify telemetry reading --- rfactor_plugin/InternalsPlugin.hpp | 14 +-- src/additional_rfactor.rs | 167 ++++++++++++++++++++++++++--- src/lib.rs | 9 +- 3 files changed, 165 insertions(+), 25 deletions(-) diff --git a/rfactor_plugin/InternalsPlugin.hpp b/rfactor_plugin/InternalsPlugin.hpp index 1992e3b..1ca21da 100644 --- a/rfactor_plugin/InternalsPlugin.hpp +++ b/rfactor_plugin/InternalsPlugin.hpp @@ -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 diff --git a/src/additional_rfactor.rs b/src/additional_rfactor.rs index 8318060..8a52b1f 100644 --- a/src/additional_rfactor.rs +++ b/src/additional_rfactor.rs @@ -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::(); - 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 { +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::(); } -impl TryFrom<&[u8]> for rF2Scoring { - type Error = AnyError; - - fn try_from(value: &[u8]) -> Result { +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], +} diff --git a/src/lib.rs b/src/lib.rs index 0d3d23f..4c98333 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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> { - let telemetry = rF2Telemetry::try_from(&self.shm[0..rF2Telemetry::SIZE])?; + pub fn query_telemetry(&self) -> Vec { + let telemetry = rF2Telemetry::from(&self.shm[0..rF2Telemetry::SIZE]); let vehicles = telemetry.vehicles(); - Ok(vehicles.to_vec()) + vehicles.to_vec() } }