start adding debugging UI

This commit is contained in:
Scott Pruett 2022-05-23 20:36:05 -04:00
parent 34a2b61757
commit e57902d80f
4 changed files with 49 additions and 28 deletions

View File

@ -1,5 +1,6 @@
{
"learned_images": {
"AAAAAAAAAAA=": ""
},
"learned_tracks": {}
}

View File

@ -13,10 +13,10 @@ use crate::{
capture,
image_processing::{self, hash_image, Region, extract_and_filter},
ocr,
state::{AppState, DebugOcrFrame, ParsedFrame, RaceState, SharedAppState},
state::{AppState, DebugOcrFrame, LapState, RaceState, SharedAppState}, config::Config,
};
fn is_finished_lap(state: &AppState, frame: &ParsedFrame) -> bool {
fn is_finished_lap(state: &AppState, frame: &LapState) -> bool {
if let Some(race) = &state.current_race {
if let Some(last_finish) = &race.last_lap_record_time {
let diff = Instant::now().duration_since(*last_finish);
@ -49,19 +49,19 @@ fn merge_with_max<T: Ord + Clone>(a: &Option<T>, b: &Option<T>) -> Option<T> {
}
}
fn merge_frames(prev: &ParsedFrame, next: &ParsedFrame) -> ParsedFrame {
ParsedFrame {
fn merge_frames(prev: &LapState, next: &LapState) -> LapState {
LapState {
lap: merge_with_max(&prev.lap, &next.lap),
health: merge_with_max(&prev.health, &next.health),
gas: merge_with_max(&prev.gas, &next.gas),
tyres: merge_with_max(&prev.tyres, &next.tyres),
lap_time: merge_with_max(&prev.lap_time, &next.lap_time),
best_time: merge_with_max(&prev.best_time, &next.best_time),
striked: false,
..Default::default()
}
}
fn handle_new_frame(state: &mut AppState, frame: ParsedFrame, image: &RgbImage) {
fn handle_new_frame(state: &mut AppState, frame: LapState, image: RgbImage) {
if frame.lap_time.is_some() {
state.last_frame = Some(frame.clone());
state.frames_without_lap = 0;
@ -71,7 +71,7 @@ fn handle_new_frame(state: &mut AppState, frame: ParsedFrame, image: &RgbImage)
race.screencap = Some(
RetainedImage::from_image_bytes(
"screencap",
&image_processing::to_png_bytes(image),
&image_processing::to_png_bytes(&image),
)
.expect("failed to save screenshot"),
);
@ -93,6 +93,7 @@ fn handle_new_frame(state: &mut AppState, frame: ParsedFrame, image: &RgbImage)
if let Some(lap) = &merged.lap {
merged.lap = Some(lap - 1);
}
merged.screenshot = Some(image);
if let Some(race) = state.current_race.as_mut() {
if let Some(prev_lap) = race.laps.last() {
@ -147,26 +148,31 @@ fn run_loop_once(capturer: &mut Capturer, state: &SharedAppState) -> Result<()>
let frame = capture::get_frame(capturer)?;
let ocr_results = ocr::ocr_all_regions(&frame, config.clone(), learned_config, ocr_cache);
let mut saved_frames = HashMap::new();
if state.lock().unwrap().debug_frames {
for region in &config.ocr_regions {
add_saved_frame(&mut saved_frames, &frame, region);
}
if let Some(track_region) = &config.track_region {
add_saved_frame(&mut saved_frames, &frame, track_region);
}
let debug_frames = save_frames_from(&frame, config.as_ref());
state.lock().unwrap().saved_frames = debug_frames;
}
{
let mut state = state.lock().unwrap();
let mut parsed = ParsedFrame::parse(&ocr_results);
handle_new_frame(&mut state, parsed, &frame);
let parsed = LapState::parse(&ocr_results);
state.raw_data = ocr_results;
state.saved_frames = saved_frames;
handle_new_frame(&mut state, parsed, frame);
}
Ok(())
}
pub fn save_frames_from(frame: &RgbImage, config: &Config) -> HashMap<String, DebugOcrFrame> {
let mut saved_frames = HashMap::new();
for region in &config.ocr_regions {
add_saved_frame(&mut saved_frames, frame, region);
}
if let Some(track_region) = &config.track_region {
add_saved_frame(&mut saved_frames, frame, track_region);
}
saved_frames
}
pub fn run_control_loop(state: SharedAppState) {
let mut capturer = Capturer::new(Display::primary().unwrap()).unwrap();
loop {

View File

@ -11,7 +11,7 @@ mod stats_writer;
use std::{
sync::{Arc, Mutex},
thread,
time::{Duration, Instant},
time::Duration,
};
use config::{Config, LearnedConfig};
@ -20,7 +20,7 @@ use eframe::{
emath::Vec2,
epaint::Color32,
};
use state::{AppState, RaceState, SharedAppState, ParsedFrame};
use state::{AppState, RaceState, SharedAppState, LapState};
use stats_writer::export_race_stats;
fn main() -> anyhow::Result<()> {
@ -120,7 +120,7 @@ fn show_race_state(ui: &mut Ui, race_name: &str, race: &mut RaceState) {
ui.label("Gas");
ui.label("Tyres");
ui.end_row();
let mut prev_lap: Option<&ParsedFrame> = None;
let mut prev_lap: Option<&LapState> = None;
for (i, lap) in race.laps.iter_mut().enumerate() {
if let Some(lap_time) = lap.lap_time {
ui.label(format!("#{}", lap.lap.unwrap_or(i + 1)));
@ -156,6 +156,18 @@ fn show_race_state(ui: &mut Ui, race_name: &str, race: &mut RaceState) {
}
}
if lap.debug {
if ui.button("Hide debug").clicked() {
lap.debug = false;
}
ui.end_row();
// TODO(DEBUG): ???
} else {
if ui.button("Debug").clicked( ){
lap.debug = true;
}
}
ui.end_row();
}
prev_lap = Some(lap);

View File

@ -7,8 +7,8 @@ use time::{OffsetDateTime, format_description};
use crate::config::{Config, LearnedConfig};
#[derive(Debug, Clone)]
pub struct ParsedFrame {
#[derive(Debug, Clone, Default)]
pub struct LapState {
pub lap: Option<usize>,
pub health: Option<usize>,
@ -19,6 +19,8 @@ pub struct ParsedFrame {
pub lap_time: Option<Duration>,
pub striked: bool,
pub screenshot: Option<RgbImage>,
pub debug: bool,
}
fn parse_duration(time: &str) -> Option<Duration> {
@ -47,7 +49,7 @@ fn parse_to_0_100(v: Option<&Option<String>>) -> Option<usize> {
check_0_100(v?.clone()?.parse::<usize>().ok()?)
}
impl ParsedFrame {
impl LapState {
pub fn parse(raw: &HashMap<String, Option<String>>) -> Self {
Self {
lap: parse_to_0_100(raw.get("lap")),
@ -56,7 +58,7 @@ impl ParsedFrame {
tyres: parse_to_0_100(raw.get("tyres")),
best_time: parse_to_duration(raw.get("best")),
lap_time: parse_to_duration(raw.get("lap_time")),
striked: false,
..Default::default()
}
}
}
@ -64,7 +66,7 @@ impl ParsedFrame {
#[derive(Default)]
pub struct RaceState {
pub race_time: Option<SystemTime>,
pub laps: Vec<ParsedFrame>,
pub laps: Vec<LapState>,
pub last_lap_record_time: Option<Instant>,
pub screencap: Option<RetainedImage>,
@ -98,9 +100,9 @@ pub struct DebugOcrFrame {
#[derive(Default)]
pub struct AppState {
pub raw_data: HashMap<String, Option<String>>,
pub last_frame: Option<ParsedFrame>,
pub last_frame: Option<LapState>,
pub buffered_frames: VecDeque<ParsedFrame>,
pub buffered_frames: VecDeque<LapState>,
pub frames_without_lap: usize,
pub current_race: Option<RaceState>,