record granular lap metrics
This commit is contained in:
parent
86a1df04ad
commit
e524758a42
|
@ -16,7 +16,7 @@ use crate::{
|
|||
image_processing::{self, extract_and_filter, hash_image, to_png_bytes, Region},
|
||||
learned_tracks::get_track_hash,
|
||||
ocr_db::OcrDatabase,
|
||||
state::{AppState, DebugOcrFrame, LapState, RaceState, SharedAppState},
|
||||
state::{AppState, DebugOcrFrame, LapState, RaceState, SharedAppState, LapMetrics},
|
||||
};
|
||||
|
||||
fn check_penalty(image: &RgbImage, config: &Config) -> bool {
|
||||
|
@ -98,6 +98,7 @@ fn handle_new_frame(state: &mut AppState, lap_state: LapState, image: &RgbImage)
|
|||
if state.current_race.is_none() {
|
||||
crate::tts::pre_race_summary(&state.tts, state.config.as_ref(), &lap_state);
|
||||
state.penalties_this_lap = 0;
|
||||
state.current_lap_metrics = LapMetrics::default();
|
||||
|
||||
let track_hash = get_track_hash(state.config.as_ref(), image);
|
||||
let track_name = state
|
||||
|
@ -124,6 +125,8 @@ fn handle_new_frame(state: &mut AppState, lap_state: LapState, image: &RgbImage)
|
|||
state.current_race = Some(race);
|
||||
}
|
||||
|
||||
state.current_lap_metrics.record(&lap_state);
|
||||
|
||||
if check_penalty(image, state.config.as_ref()) {
|
||||
if !state.detecting_penalty {
|
||||
state.penalties_this_lap += 1;
|
||||
|
@ -147,6 +150,9 @@ fn handle_new_frame(state: &mut AppState, lap_state: LapState, image: &RgbImage)
|
|||
if let Some(lap) = &merged.lap {
|
||||
merged.lap = Some(lap - 1);
|
||||
}
|
||||
merged.metrics = state.current_lap_metrics.clone();
|
||||
state.current_lap_metrics = LapMetrics::default();
|
||||
|
||||
merged.screenshot = Some(to_png_bytes(image));
|
||||
merged.penalties = state.penalties_this_lap;
|
||||
state.penalties_this_lap = 0;
|
||||
|
|
46
src/state.rs
46
src/state.rs
|
@ -6,11 +6,32 @@ use std::{
|
|||
|
||||
use egui_extras::RetainedImage;
|
||||
use image::RgbImage;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::{format_description, OffsetDateTime};
|
||||
|
||||
use crate::{config::Config, learned_tracks::LearnedTracks, ocr_db::OcrDatabase, tts::Tts};
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct LapMetrics {
|
||||
pub position: Vec<u16>,
|
||||
pub health: Vec<u8>,
|
||||
pub gas: Vec<u8>,
|
||||
pub tyres: Vec<u8>,
|
||||
}
|
||||
fn record_metric<T: Copy>(vec: &mut Vec<T>, val: &Option<T>) {
|
||||
if let Some(v) = val {
|
||||
vec.push(*v);
|
||||
}
|
||||
}
|
||||
impl LapMetrics {
|
||||
pub fn record(&mut self, lap: &LapState) {
|
||||
record_metric(&mut self.position, &lap.position);
|
||||
record_metric(&mut self.gas, &lap.gas);
|
||||
record_metric(&mut self.tyres, &lap.tyres);
|
||||
record_metric(&mut self.health, &lap.health);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct LapState {
|
||||
pub lap: Option<u16>,
|
||||
|
@ -32,6 +53,8 @@ pub struct LapState {
|
|||
pub debug: bool,
|
||||
|
||||
pub penalties: usize,
|
||||
|
||||
pub metrics: LapMetrics,
|
||||
}
|
||||
|
||||
fn parse_duration(time: &str) -> Option<Duration> {
|
||||
|
@ -151,7 +174,11 @@ impl RaceState {
|
|||
}
|
||||
|
||||
pub fn fastest_lap(&self) -> Option<Duration> {
|
||||
self.laps.iter().filter(|lap| !lap.striked).filter_map(|lap| lap.lap_time).min()
|
||||
self.laps
|
||||
.iter()
|
||||
.filter(|lap| !lap.striked)
|
||||
.filter_map(|lap| lap.lap_time)
|
||||
.min()
|
||||
}
|
||||
|
||||
pub fn tyre_wear(&self) -> Option<u8> {
|
||||
|
@ -163,7 +190,12 @@ impl RaceState {
|
|||
}
|
||||
|
||||
pub fn latest_gas_diff(&self, to: u8) -> Option<u8> {
|
||||
let last_gas = self.laps.iter().last().map(|l| l.gas).unwrap_or(Some(100))?;
|
||||
let last_gas = self
|
||||
.laps
|
||||
.iter()
|
||||
.last()
|
||||
.map(|l| l.gas)
|
||||
.unwrap_or(Some(100))?;
|
||||
if to < last_gas {
|
||||
Some(last_gas - to)
|
||||
} else {
|
||||
|
@ -171,7 +203,12 @@ impl RaceState {
|
|||
}
|
||||
}
|
||||
pub fn latest_tyre_diff(&self, to: u8) -> Option<u8> {
|
||||
let last_tyres = self.laps.iter().last().map(|l| l.tyres).unwrap_or(Some(100))?;
|
||||
let last_tyres = self
|
||||
.laps
|
||||
.iter()
|
||||
.last()
|
||||
.map(|l| l.tyres)
|
||||
.unwrap_or(Some(100))?;
|
||||
if to < last_tyres {
|
||||
Some(last_tyres - to)
|
||||
} else {
|
||||
|
@ -190,6 +227,7 @@ pub struct DebugOcrFrame {
|
|||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct AppState {
|
||||
pub last_frame: Option<LapState>,
|
||||
pub current_lap_metrics: LapMetrics,
|
||||
|
||||
pub buffered_frames: VecDeque<LapState>,
|
||||
|
||||
|
|
Loading…
Reference in New Issue