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},
|
image_processing::{self, extract_and_filter, hash_image, to_png_bytes, Region},
|
||||||
learned_tracks::get_track_hash,
|
learned_tracks::get_track_hash,
|
||||||
ocr_db::OcrDatabase,
|
ocr_db::OcrDatabase,
|
||||||
state::{AppState, DebugOcrFrame, LapState, RaceState, SharedAppState},
|
state::{AppState, DebugOcrFrame, LapState, RaceState, SharedAppState, LapMetrics},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn check_penalty(image: &RgbImage, config: &Config) -> bool {
|
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() {
|
if state.current_race.is_none() {
|
||||||
crate::tts::pre_race_summary(&state.tts, state.config.as_ref(), &lap_state);
|
crate::tts::pre_race_summary(&state.tts, state.config.as_ref(), &lap_state);
|
||||||
state.penalties_this_lap = 0;
|
state.penalties_this_lap = 0;
|
||||||
|
state.current_lap_metrics = LapMetrics::default();
|
||||||
|
|
||||||
let track_hash = get_track_hash(state.config.as_ref(), image);
|
let track_hash = get_track_hash(state.config.as_ref(), image);
|
||||||
let track_name = state
|
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_race = Some(race);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.current_lap_metrics.record(&lap_state);
|
||||||
|
|
||||||
if check_penalty(image, state.config.as_ref()) {
|
if check_penalty(image, state.config.as_ref()) {
|
||||||
if !state.detecting_penalty {
|
if !state.detecting_penalty {
|
||||||
state.penalties_this_lap += 1;
|
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 {
|
if let Some(lap) = &merged.lap {
|
||||||
merged.lap = Some(lap - 1);
|
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.screenshot = Some(to_png_bytes(image));
|
||||||
merged.penalties = state.penalties_this_lap;
|
merged.penalties = state.penalties_this_lap;
|
||||||
state.penalties_this_lap = 0;
|
state.penalties_this_lap = 0;
|
||||||
|
|
46
src/state.rs
46
src/state.rs
|
@ -6,11 +6,32 @@ use std::{
|
||||||
|
|
||||||
use egui_extras::RetainedImage;
|
use egui_extras::RetainedImage;
|
||||||
use image::RgbImage;
|
use image::RgbImage;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use time::{format_description, OffsetDateTime};
|
use time::{format_description, OffsetDateTime};
|
||||||
|
|
||||||
use crate::{config::Config, learned_tracks::LearnedTracks, ocr_db::OcrDatabase, tts::Tts};
|
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)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct LapState {
|
pub struct LapState {
|
||||||
pub lap: Option<u16>,
|
pub lap: Option<u16>,
|
||||||
|
@ -32,6 +53,8 @@ pub struct LapState {
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
|
|
||||||
pub penalties: usize,
|
pub penalties: usize,
|
||||||
|
|
||||||
|
pub metrics: LapMetrics,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_duration(time: &str) -> Option<Duration> {
|
fn parse_duration(time: &str) -> Option<Duration> {
|
||||||
|
@ -151,7 +174,11 @@ impl RaceState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fastest_lap(&self) -> Option<Duration> {
|
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> {
|
pub fn tyre_wear(&self) -> Option<u8> {
|
||||||
|
@ -163,7 +190,12 @@ impl RaceState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn latest_gas_diff(&self, to: u8) -> Option<u8> {
|
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 {
|
if to < last_gas {
|
||||||
Some(last_gas - to)
|
Some(last_gas - to)
|
||||||
} else {
|
} else {
|
||||||
|
@ -171,7 +203,12 @@ impl RaceState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn latest_tyre_diff(&self, to: u8) -> Option<u8> {
|
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 {
|
if to < last_tyres {
|
||||||
Some(last_tyres - to)
|
Some(last_tyres - to)
|
||||||
} else {
|
} else {
|
||||||
|
@ -190,6 +227,7 @@ pub struct DebugOcrFrame {
|
||||||
#[derive(Default, Serialize, Deserialize)]
|
#[derive(Default, Serialize, Deserialize)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub last_frame: Option<LapState>,
|
pub last_frame: Option<LapState>,
|
||||||
|
pub current_lap_metrics: LapMetrics,
|
||||||
|
|
||||||
pub buffered_frames: VecDeque<LapState>,
|
pub buffered_frames: VecDeque<LapState>,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue