mod engine; use engine::*; mod camera; mod config; mod drone; mod helpers; mod logger; mod rendering; mod simulation; mod graphics_util; use crate::drone::input::*; use crate::simulation::{SimMode, Simulation}; use crate::config::SimulationConfig; use helpers::list_files; use std::fs; const INPUTS_DIR: &str = "inputs/"; const CONFIGS_DIR: &str = "configurations/final/"; const RESULTS_DIR: &str = "results/"; use std::path::PathBuf; use std::thread::JoinHandle; fn main() { run_batch(); } fn run_batch() { let _ = fs::remove_dir_all(RESULTS_DIR); let _ = fs::create_dir_all(RESULTS_DIR); let input_files = list_files(INPUTS_DIR); let config_files = list_files(CONFIGS_DIR); let mut handles: Vec> = Default::default(); for input_path in input_files { for config_path in &config_files { let cp = config_path.clone(); let ip = input_path.clone(); handles.push(std::thread::spawn(move || { run(&ip, &cp); })); } } for handle in handles { handle.join().unwrap(); } println!("All simulations completed."); } fn run(input_path: &PathBuf, config_path: &PathBuf) { let input_name = input_path.file_stem().unwrap().to_string_lossy(); let inputs = InputRecording::load_from_file(input_path.to_str().unwrap()) .expect("Failed to load input recording"); let config_name = config_path.file_stem().unwrap().to_string_lossy(); let config: SimulationConfig = toml::from_str(&fs::read_to_string(config_path).unwrap()).expect("Invalid config file"); println!( "Running simulation: input={} config={}", input_name, config_name ); let mut world = World::new(config.tickrate); let drone = drone::Drone::new( &mut world, Box::new(drone::stacked::StackedController::new(config.clone())), drone::MotorCharacteristics { max_thrust: config.max_thrust, max_torque: config.max_torque, time_constant: config.time_constant, ..Default::default() }, config.mass, ); let result_file = format!("{}/{}_{}.csv", RESULTS_DIR, input_name, config_name); let mut sim = Simulation::new( drone, world, SimMode::Playback(inputs.clone(), 0.0), Some(result_file), config.drone_tick_rate, ); sim.run().unwrap(); } async fn run_record(output: String, config_path: &PathBuf) { println!( "Recording inputs to {}, using config {}", output, config_path.to_str().unwrap_or("") ); let config: SimulationConfig = toml::from_str(&fs::read_to_string(config_path).unwrap()).expect("Invalid config file"); let mut world = World::new(config.tickrate); let drone = drone::Drone::new( &mut world, Box::new(drone::stacked::StackedController::new(config.clone())), drone::MotorCharacteristics { max_thrust: config.max_thrust, max_torque: config.max_torque, time_constant: config.time_constant, ..Default::default() }, config.mass, ); let mut sim = Simulation::new( drone, world, SimMode::Record(InputRecording::default(), output), None, config.drone_tick_rate, ); sim.run_and_render().await.unwrap(); }