it works!! i think

This commit is contained in:
Alex Janka 2022-02-23 14:35:49 +11:00
parent cbe2e07969
commit 740f06f971
4 changed files with 274 additions and 131 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/target
/logs

160
Cargo.lock generated
View file

@ -34,6 +34,37 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"lazy_static",
"memchr",
"regex-automata",
"serde",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]]
name = "clap"
version = "3.1.1"
@ -64,6 +95,37 @@ dependencies = [
"syn",
]
[[package]]
name = "csv"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
dependencies = [
"bstr",
"csv-core",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "csv-core"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
dependencies = [
"memchr",
]
[[package]]
name = "fastrand"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
dependencies = [
"instant",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
@ -95,6 +157,21 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]]
name = "itoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -113,6 +190,25 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "os_str_bytes"
version = "6.0.0"
@ -164,6 +260,36 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
dependencies = [
"bitflags",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "ryu"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]]
name = "serde"
version = "1.0.136"
@ -206,8 +332,25 @@ name = "telemetry"
version = "0.1.0"
dependencies = [
"bincode",
"chrono",
"clap",
"csv",
"serde",
"tempfile",
]
[[package]]
name = "tempfile"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
dependencies = [
"cfg-if",
"fastrand",
"libc",
"redox_syscall",
"remove_dir_all",
"winapi",
]
[[package]]
@ -225,6 +368,17 @@ version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
@ -237,6 +391,12 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "winapi"
version = "0.3.9"

View file

@ -6,6 +6,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "3.1.1", features = ["derive"] }
serde = { version = "1.0.136", features = ["derive"] }
bincode = "1.3.3"
clap = { version = "3.1", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
bincode = "1.3"
csv = "1.1"
chrono = "0.4"
tempfile = "3.3"

View file

@ -1,9 +1,12 @@
use std::net;
use std::net::UdpSocket;
use std::path::Path;
use std::{fs, net};
use bincode;
use chrono::Local;
use clap::Parser;
use serde::{Deserialize, Serialize};
use tempfile::tempfile;
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
@ -16,161 +19,86 @@ struct Args {
#[clap(short, long)]
verbose: bool,
#[clap(short, long)]
errors: bool,
}
#[derive(Serialize, Deserialize, Debug)]
struct Telemetry {
// is_race_on: i32,
// timestamp_ms: u32,
// engine_max_rpm: f32,
// engine_idle_rpm: f32,
// current_engine_rpm: f32,
// acceleration_x: f32,
// acceleration_y: f32,
// acceleration_z: f32,
// velocity_x: f32,
// velocity_y: f32,
// velocity_z: f32,
// angular_velocity_x: f32,
// angular_velocity_y: f32,
// angular_velocity_z: f32,
// yaw: f32,
// pitch: f32,
// roll: f32,
// normalized_suspension_travel_front_left: f32,
// normalized_suspension_travel_front_right: f32,
// normalized_suspension_travel_rear_left: f32,
// normalized_suspension_travel_rear_right: f32,
// tire_slip_ratio_front_left: f32,
// tire_slip_ratio_front_right: f32,
// tire_slip_ratio_rear_left: f32,
// tire_slip_ratio_rear_right: f32,
// wheel_rotation_speed_front_left: f32,
// wheel_rotation_speed_front_right: f32,
// wheel_rotation_speed_rear_left: f32,
// wheel_rotation_speed_rear_right: f32,
// wheel_on_rumble_strip_front_left: i32,
// wheel_on_rumble_strip_front_right: i32,
// wheel_on_rumble_strip_rear_left: i32,
// wheel_on_rumble_strip_rear_right: i32,
// wheel_in_puddle_depth_front_left: f32,
// wheel_in_puddle_depth_front_right: f32,
// wheel_in_puddle_depth_rear_left: f32,
// wheel_in_puddle_depth_rear_right: f32,
// surface_rumble_front_left: f32,
// surface_rumble_front_right: f32,
// surface_rumble_rear_left: f32,
// surface_rumble_rear_right: f32,
// tire_slip_angle_front_left: f32,
// tire_slip_angle_front_right: f32,
// tire_slip_angle_rear_left: f32,
// tire_slip_angle_rear_right: f32,
// tire_combined_slip_front_left: f32,
// tire_combined_slip_front_right: f32,
// tire_combined_slip_rear_left: f32,
// tire_combined_slip_rear_right: f32,
// suspension_travel_meters_front_left: f32,
// suspension_travel_meters_front_right: f32,
// suspension_travel_meters_rear_left: f32,
// suspension_travel_meters_rear_right: f32,
// car_ordinal: i32,
// car_class: i32,
// car_performance_index: i32,
// drivetrain_type: i32,
// num_cylinders: i32,
// horizon_placeholder1: u32,
// horizon_placeholder2: u32,
// horizon_placeholder3: u32,
// position_x: f32,
// position_y: f32,
// position_z: f32,
// speed: f32,
// power: f32,
// torque: f32,
// tire_temp_front_left: f32,
// tire_temp_front_right: f32,
// tire_temp_rear_left: f32,
// tire_temp_rear_right: f32,
// boost: f32,
// fuel: f32,
// distance_traveled: f32,
// best_lap: f32,
// last_lap: f32,
// current_lap: f32,
// current_race_time: f32,
// lap_number: u16,
// race_position: u8,
// accel: u8,
// brake: u8,
// clutch: u8,
// hand_brake: u8,
// gear: u8,
// steer: i8,
// normalized_driving_line: i8,
// normalized_ai_brake_difference: i8,
// BORDER
is_race_on: i32,
time_stamp_ms: u32,
engine_max_rpm: f32,
engine_idle_rpm: f32,
current_engine_rpm: f32,
acceleration_x: f32,
acceleration_x: f32, // local space: X = right, Y = up, Z = forward
acceleration_y: f32,
acceleration_z: f32,
velocity_x: f32,
velocity_x: f32, // local space: X = right, Y = up, Z = forward
velocity_y: f32,
velocity_z: f32,
angular_velocity_x: f32,
angular_velocity_x: f32, // local space: X = pitch, Y = yaw, Z = roll
angular_velocity_y: f32,
angular_velocity_z: f32,
yaw: f32,
pitch: f32,
roll: f32,
normalized_suspension_travel_front_left: f32,
normalized_suspension_travel_front_left: f32, // Suspension travel normalized: 0.0f = max stretch; 1.0 = max compression
normalized_suspension_travel_front_right: f32,
normalized_suspension_travel_rear_left: f32,
normalized_suspension_travel_rear_right: f32,
tire_slip_ratio_front_left: f32,
tire_slip_ratio_front_left: f32, // Tire normalized slip ratio, = 0 means 100% grip and |ratio| > 1.0 means loss of grip.
tire_slip_ratio_front_right: f32,
tire_slip_ratio_rear_left: f32,
tire_slip_ratio_rear_right: f32,
wheel_rotation_speed_front_left: f32,
wheel_rotation_speed_front_left: f32, // Wheel rotation speed radians/sec.
wheel_rotation_speed_front_right: f32,
wheel_rotation_speed_rear_left: f32,
wheel_rotation_speed_rear_right: f32,
wheel_on_rumble_strip_front_left: i32,
wheel_on_rumble_strip_front_left: i32, // = 1 when wheel is on rumble strip, = 0 when off.
wheel_on_rumble_strip_front_right: i32,
wheel_on_rumble_strip_rear_left: i32,
wheel_on_rumble_strip_rear_right: i32,
wheel_in_puddle_depth_front_left: f32,
wheel_in_puddle_depth_front_left: f32, // = from 0 to 1, where 1 is the deepest puddle
wheel_in_puddle_depth_front_right: f32,
wheel_in_puddle_depth_rear_left: f32,
wheel_in_puddle_depth_rear_right: f32,
surface_rumble_front_left: f32,
surface_rumble_front_left: f32, // Non-dimensional surface rumble values passed to controller force feedback
surface_rumble_front_right: f32,
surface_rumble_rear_left: f32,
surface_rumble_rear_right: f32,
tire_slip_angle_front_left: f32,
tire_slip_angle_front_left: f32, // Tire normalized slip angle, = 0 means 100% grip and |angle| > 1.0 means loss of grip.
tire_slip_angle_front_right: f32,
tire_slip_angle_rear_left: f32,
tire_slip_angle_rear_right: f32,
tire_combined_slip_front_left: f32,
tire_combined_slip_front_left: f32, // Tire normalized combined slip, = 0 means 100% grip and |slip| > 1.0 means loss of grip.
tire_combined_slip_front_right: f32,
tire_combined_slip_rear_left: f32,
tire_combined_slip_rear_right: f32,
suspension_travel_meters_front_left: f32,
suspension_travel_meters_front_left: f32, // Actual suspension travel in meters
suspension_travel_meters_front_right: f32,
suspension_travel_meters_rear_left: f32,
suspension_travel_meters_rear_right: f32,
car_ordinal: i32,
car_class: i32,
car_performance_index: i32,
drivetrai32ype: i32,
drivetraintype: i32, // 0 = FWD, 1 = RWD, 2 = AWD
num_cylinders: i32,
car_type: i32,
unknown1: u8,
unknown2: u8,
unknown3: u8,
@ -179,17 +107,20 @@ struct Telemetry {
unknown6: u8,
unknown7: u8,
unknown8: u8,
car_ordinal: i32,
position_x: f32,
position_x: f32, // meters
position_y: f32,
position_z: f32,
speed: f32,
power: f32,
torque: f32,
speed: f32, // meters per second
power: f32, // watts
torque: f32, // newton meters
tire_temp_front_left: f32,
tire_temp_front_right: f32,
tire_temp_rear_left: f32,
tire_temp_rear_right: f32,
boost: f32,
fuel: f32,
distance_traveled: f32,
@ -197,47 +128,95 @@ struct Telemetry {
last_lap: f32,
current_lap: f32,
current_race_time: f32,
lap_number: i16,
race_position: u8,
accel: u8,
brake: u8,
clutch: u8,
handbrake: u8,
gear: u8,
steer: i8,
normalized_driving_line: i8,
normalized_ai_brake_difference: i8,
}
fn listen(socket: &net::UdpSocket, mut buffer: &mut [u8]) -> usize {
let (number_of_bytes, _) = socket.recv_from(&mut buffer).expect("no data received");
let number_of_bytes = match socket.recv_from(&mut buffer) {
Ok((num, _)) => num,
// skip packets if they're too big
Err(_) => 0,
};
number_of_bytes
}
fn main() {
let args = Args::parse();
let ip = format!("0.0.0.0:{}", args.port.to_string());
if args.verbose {
if args.folder != "" {
println!("Folder: {}", args.folder);
} else {
println!("No folder specified - not saving logs");
}
if args.folder != "" {
println!("Saving logs to {}", args.folder);
} else {
println!("No folder specified - saving to current directory");
}
let folder_path = Path::new(&args.folder);
fs::create_dir_all(folder_path).expect("couldnt create log directory!");
let socket = UdpSocket::bind(ip).expect("couldnt bind");
let mut buf = [0; 500];
while listen(&socket, &mut buf) != 0 {
let deserialised: Telemetry = bincode::deserialize(&buf).expect("couldnt deser");
if deserialised.current_engine_rpm == 0.0 {
continue;
let mut writer = csv::Writer::from_writer(tempfile().expect("couldnt open tempfile"));
let mut inrace = false;
'listener: while listen(&socket, &mut buf) != 0 {
let deserialised: Telemetry = bincode::deserialize(&buf).expect("error parsing packet");
if deserialised.is_race_on == 0 {
continue 'listener;
}
if args.verbose {
println!(
"Gear: {}, RPM: {}",
deserialised.gear, deserialised.current_engine_rpm
);
if args.verbose {}
if inrace {
if deserialised.race_position == 0 {
// coming out of race
inrace = false;
writer.flush().expect("couldnt flush to file");
println!(
"{}: no longer in race",
&Local::now().format("%H:%M:%S").to_string()
);
continue 'listener;
} else {
// still in race
}
} else {
if deserialised.race_position > 0 {
// getting into race
inrace = true;
println!(
"{}: entering race",
&Local::now().format("%H:%M:%S").to_string()
);
println!("car class: {}", deserialised.car_performance_index);
// open file for this race
// filename format: timestamp _ car class _ car ordinal
writer = csv::Writer::from_writer(
fs::File::create(folder_path.join(format!(
"{}_{}_{}{}",
&Local::now().format("%Y-%m-%d_%H-%M").to_string(),
deserialised.car_performance_index,
deserialised.car_ordinal,
".csv",
)))
.expect("couldnt open file"),
);
} else {
// still not in race
continue 'listener;
}
}
writer.serialize(deserialised).expect("couldnt serialise");
}
}