From f8c7761d8ceab78dd0a0deef32cce8702ebaf832 Mon Sep 17 00:00:00 2001 From: Franchioping Date: Tue, 6 Jan 2026 16:41:14 +0000 Subject: [PATCH] before cargo fix --- Cargo.lock | 2 +- Cargo.toml | 10 +- src/drone/fpvcontroller.rs | 2 +- src/main.rs | 208 ++++++++++++++----------------------- src/main_batch.rs | 170 ++++++++++++++++++++++++++++++ 5 files changed, 255 insertions(+), 137 deletions(-) create mode 100644 src/main_batch.rs diff --git a/Cargo.lock b/Cargo.lock index 378721d..c99303f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ version = 4 [[package]] -name = "RaylibRustPhysics" +name = "RustPhysicsMQ" version = "0.1.0" dependencies = [ "clearscreen", diff --git a/Cargo.toml b/Cargo.toml index 03674d7..8c7c106 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "RaylibRustPhysics" +name = "RustPhysicsMQ" version = "0.1.0" edition = "2024" -default-run = "RaylibRustPhysics" +default-run = "RustPhysicsMQ" [dependencies] macroquad = "0.4.14" @@ -17,9 +17,11 @@ serde = {version = "1.0.228", features = ["serde_derive"]} toml = "0.9.8" + [[bin]] -name = "tools" -path = "src/tools/main.rs" +name = "batch" +path = "src/main_batch.rs" + [profile.dev.package.rapier3d] opt-level = 3 diff --git a/src/drone/fpvcontroller.rs b/src/drone/fpvcontroller.rs index 0887fa4..0d80ab4 100644 --- a/src/drone/fpvcontroller.rs +++ b/src/drone/fpvcontroller.rs @@ -3,7 +3,7 @@ use std::any::Any; use crate::drone::controller::DroneController; -use crate::drone::JoystickInput; +pub use crate::drone::JoystickInput; pub struct FPVController { input: JoystickInput, diff --git a/src/main.rs b/src/main.rs index 2fd2c54..552fa93 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,154 +1,55 @@ +use gilrs; use macroquad::prelude as mq; +use nalgebra as na; +use rapier3d::prelude::*; mod engine; use engine::*; + mod camera; -mod config; mod drone; -mod helpers; 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/"; -const RESULTS_DIR: &str = "results/"; +use crate::{drone::fpvcontroller::JoystickInput, rendering::Renderer}; fn window_conf() -> mq::Conf { mq::Conf { window_title: "RustDroneSim".to_owned(), window_resizable: true, + // fullscreen: true, platform: mq::miniquad::conf::Platform { + // linux_backend: mq::miniquad::conf::LinuxBackend::WaylandOnly, ..Default::default() }, ..Default::default() } } -use std::env; -use std::path::PathBuf; -use std::thread::JoinHandle; - -enum RunMode { - Batch, - Record { output: String }, -} - -fn parse_cli() -> RunMode { - let mut args = env::args().skip(1); - - match args.next().as_deref() { - Some("record") => { - let output = args.next().expect("record mode requires output file path"); - RunMode::Record { output } - } - Some("batch") | None => RunMode::Batch, - Some(other) => panic!("Unknown mode: {}", other), - } -} - #[macroquad::main(window_conf)] async fn main() { - match parse_cli() { - RunMode::Batch => run_batch().await, - RunMode::Record { output } => run_record(output).await, - } -} + /* World Setup */ + let mut world = World::default(); -async fn run_batch() { - fs::remove_dir_all(RESULTS_DIR).unwrap(); - fs::create_dir_all(RESULTS_DIR).unwrap(); - - 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_inputs_from_csv(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 + world.register_free_collider( + ColliderBuilder::cuboid(30.0, 1.0, 30.0) + .translation(vector![0.0, -2.0, 0.0]) + .restitution(0.5) + .build(), + None, ); - /* World */ - let mut world = World::new(config.tickrate); - - /* Drone */ - let drone = drone::Drone::new( + let mut drone_controller = drone::pidcontroller::PIDController::default(); + drone_controller.set_input(JoystickInput { + throttle_input: 0.75, + yaw_input: 0.4, + roll_input: 0.7, + pitch_input: 0.0, + }); + let mut drone_obj = drone::Drone::new( &mut world, - Box::new(drone::pidcontroller::PIDController { - target_rate: config.target_rate, - proportional_multiplier: config.proportional(), - integral_multiplier: config.integral(), - diferential_multiplier: config.diferential(), - ..Default::default() - }), - drone::MotorCharacteristics { - max_thrust: config.max_thrust, - max_torque: config.max_torque, - ..Default::default() - }, - config.mass, - ); - - let result_file = format!("{}/{}_{}.csv", RESULTS_DIR, input_name, config_name); - - let mut sim = Simulation::new( - drone, - world, - false, - SimMode::Playback(inputs.clone(), 0.0), - Some(result_file), - config.drone_tick_rate, - ); - - sim.run().unwrap(); -} - -async fn run_record(output: String) { - println!("Recording inputs to {}", output); - - let tickrate = 60000.0; - let mut world = World::new(tickrate); - - let drone = drone::Drone::new( - &mut world, - Box::new(drone::pidcontroller::PIDController { - ..Default::default() - }), + Box::new(drone_controller), drone::MotorCharacteristics { max_thrust: 2.6, max_torque: 0.5, @@ -157,14 +58,59 @@ async fn run_record(output: String) { 0.350, ); - let mut sim = Simulation::new( - drone, - world, - true, - SimMode::Record(InputRecording::default(), output), - None, - 600, + /* Renderer Setup */ + let camera = camera::AttachedCamera::new( + drone_obj.rb_handle, + vector![1.0, 0.0, 0.0], + vector![0.5, 0.0, 0.0], ); + let mut renderer = Renderer::new(Box::new(camera)); - sim.run().unwrap(); + renderer.light.set_location( + vector![70.0, 150.0, -90.0].into(), + vector![-0.4, -0.7, 0.6].into(), + ); + renderer.update_light(&world); + + let mut input = JoystickInput::default(); + + loop { + renderer.update_camera(&world); + + if mq::is_key_pressed(mq::KeyCode::Q) { + break; + } + + // Physics + world.step(); + let _ = clearscreen::clear(); + drone_obj.process_tick(&mut world); + + // Rendering + renderer.draw(&mut world); + + if world.tick % (20) == 0 { + // renderer.update_light(&world); + // world.clear_ofb(); + mq::next_frame().await; + } + } +} + +fn add_objects(world: &mut World) { + for i in 0..1 { + let body = world.register_body( + RigidBodyBuilder::dynamic() + .translation(vector![0.0, 50.0 + i as f32, 0.0]) + .rotation(vector![std::f32::consts::PI / 4.2, i as f32, i as f32]) + .build(), + ); + world.register_collider( + ColliderBuilder::cuboid(2.0, 2.0, 2.0) + .restitution(0.1) + .build(), + body, + None, + ); + } } diff --git a/src/main_batch.rs b/src/main_batch.rs new file mode 100644 index 0000000..2fd2c54 --- /dev/null +++ b/src/main_batch.rs @@ -0,0 +1,170 @@ +use macroquad::prelude as mq; + +mod engine; +use engine::*; +mod camera; +mod config; +mod drone; +mod helpers; +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/"; +const RESULTS_DIR: &str = "results/"; + +fn window_conf() -> mq::Conf { + mq::Conf { + window_title: "RustDroneSim".to_owned(), + window_resizable: true, + platform: mq::miniquad::conf::Platform { + ..Default::default() + }, + ..Default::default() + } +} + +use std::env; +use std::path::PathBuf; +use std::thread::JoinHandle; + +enum RunMode { + Batch, + Record { output: String }, +} + +fn parse_cli() -> RunMode { + let mut args = env::args().skip(1); + + match args.next().as_deref() { + Some("record") => { + let output = args.next().expect("record mode requires output file path"); + RunMode::Record { output } + } + Some("batch") | None => RunMode::Batch, + Some(other) => panic!("Unknown mode: {}", other), + } +} + +#[macroquad::main(window_conf)] +async fn main() { + match parse_cli() { + RunMode::Batch => run_batch().await, + RunMode::Record { output } => run_record(output).await, + } +} + +async fn run_batch() { + fs::remove_dir_all(RESULTS_DIR).unwrap(); + fs::create_dir_all(RESULTS_DIR).unwrap(); + + 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_inputs_from_csv(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 + ); + + /* World */ + let mut world = World::new(config.tickrate); + + /* Drone */ + let drone = drone::Drone::new( + &mut world, + Box::new(drone::pidcontroller::PIDController { + target_rate: config.target_rate, + proportional_multiplier: config.proportional(), + integral_multiplier: config.integral(), + diferential_multiplier: config.diferential(), + ..Default::default() + }), + drone::MotorCharacteristics { + max_thrust: config.max_thrust, + max_torque: config.max_torque, + ..Default::default() + }, + config.mass, + ); + + let result_file = format!("{}/{}_{}.csv", RESULTS_DIR, input_name, config_name); + + let mut sim = Simulation::new( + drone, + world, + false, + SimMode::Playback(inputs.clone(), 0.0), + Some(result_file), + config.drone_tick_rate, + ); + + sim.run().unwrap(); +} + +async fn run_record(output: String) { + println!("Recording inputs to {}", output); + + let tickrate = 60000.0; + let mut world = World::new(tickrate); + + let drone = drone::Drone::new( + &mut world, + Box::new(drone::pidcontroller::PIDController { + ..Default::default() + }), + drone::MotorCharacteristics { + max_thrust: 2.6, + max_torque: 0.5, + ..Default::default() + }, + 0.350, + ); + + let mut sim = Simulation::new( + drone, + world, + true, + SimMode::Record(InputRecording::default(), output), + None, + 600, + ); + + sim.run().unwrap(); +}