diff --git a/src/framework/scheduler/looper/mod.rs b/src/framework/scheduler/looper/mod.rs index 30849be..0565f75 100644 --- a/src/framework/scheduler/looper/mod.rs +++ b/src/framework/scheduler/looper/mod.rs @@ -25,9 +25,9 @@ use likely_stable::{likely, unlikely}; use log::debug; use log::info; use policy::{ - controll::pid_control, - evolution::{evaluate_fitness, load_pid_params, mutate_params, open_database, Fitness}, - PidParams, + controll::calculate_control, + evolution::{evaluate_fitness, load_control_params, mutate_params, open_database, Fitness}, + ControllerParams, }; use rusqlite::Connection; @@ -54,16 +54,17 @@ enum State { } struct EvolutionState { - pid_params: PidParams, - mutated_pid_params: PidParams, + controller_params: ControllerParams, + mutated_controller_params: ControllerParams, mutate_timer: Instant, fitness: Fitness, } impl EvolutionState { pub fn reset(&mut self, database: &Connection, pkg: &str) { - self.pid_params = load_pid_params(database, pkg).unwrap_or_else(|_| PidParams::default()); - self.mutated_pid_params = self.pid_params; + self.controller_params = + load_control_params(database, pkg).unwrap_or_else(|_| ControllerParams::default()); + self.mutated_controller_params = self.controller_params; self.fitness = Fitness::MIN; } @@ -79,13 +80,13 @@ impl EvolutionState { if let Some(fitness) = evaluate_fitness(buffer, cpu_temp_watcher, config, mode) { if fitness > self.fitness { - self.pid_params = self.mutated_pid_params; + self.controller_params = self.mutated_controller_params; } self.fitness = fitness; } - self.mutated_pid_params = mutate_params(self.pid_params); + self.mutated_controller_params = mutate_params(self.controller_params); } } } @@ -147,8 +148,8 @@ impl Looper { delay_timer: Instant::now(), }, evolution_state: EvolutionState { - pid_params: PidParams::default(), - mutated_pid_params: PidParams::default(), + controller_params: ControllerParams::default(), + mutated_controller_params: ControllerParams::default(), mutate_timer: Instant::now(), fitness: Fitness::MIN, }, @@ -259,11 +260,11 @@ impl Looper { self.fas_state.mode, ); - pid_control( + calculate_control( buffer, &mut self.config, self.fas_state.mode, - self.evolution_state.mutated_pid_params, + self.evolution_state.mutated_controller_params, ) .unwrap_or_default() } else { diff --git a/src/framework/scheduler/looper/policy/controll.rs b/src/framework/scheduler/looper/policy/controll.rs index 9d48ecc..7bec4cf 100644 --- a/src/framework/scheduler/looper/policy/controll.rs +++ b/src/framework/scheduler/looper/policy/controll.rs @@ -18,14 +18,14 @@ use likely_stable::unlikely; #[cfg(debug_assertions)] use log::debug; -use super::{super::buffer::Buffer, PidParams}; +use super::{super::buffer::Buffer, ControllerParams}; use crate::framework::prelude::*; -pub fn pid_control( +pub fn calculate_control( buffer: &Buffer, config: &mut Config, mode: Mode, - pid_params: PidParams, + controller_params: ControllerParams, ) -> Option { if unlikely(buffer.frametime_state.frametimes.len() < 60) { return None; @@ -47,51 +47,19 @@ pub fn pid_control( let margin = Duration::from_millis(margin); let target = Duration::from_secs(1) + margin; - Some(pid_control_inner( - pid_params, - frame, - target, - buffer - .frametime_state - .frametimes - .iter() - .copied() - .take(30) - .sum::() - .mul_f64(target_fps), - buffer - .frametime_state - .frametimes - .iter() - .copied() - .take(60) - .sum::() - .mul_f64(target_fps), - )) + Some(calculate_control_inner(controller_params, frame, target)) } -fn pid_control_inner( - pid_params: PidParams, +fn calculate_control_inner( + controller_params: ControllerParams, current_frametime: Duration, target_frametime: Duration, - last_30_frametimes_sum: Duration, - last_60_frametimes_sum: Duration, ) -> isize { let error_p = - (current_frametime.as_nanos() as f64 - target_frametime.as_nanos() as f64) * pid_params.kp; - let error_i = (target_frametime.as_nanos() as f64) - .mul_add(-30.0, last_30_frametimes_sum.as_nanos() as f64) - * pid_params.ki; - let error_d = (last_30_frametimes_sum.as_nanos() as f64) - .mul_add(2.0, -(last_60_frametimes_sum.as_nanos() as f64)) - * pid_params.kd; + (current_frametime.as_nanos() as f64 - target_frametime.as_nanos() as f64) * controller_params.kp; #[cfg(debug_assertions)] - { - debug!("error_p {error_p}"); - debug!("error_i {error_i}"); - debug!("error_d {error_d}"); - } + debug!("error_p {error_p}"); - (error_p/* + error_i + error_d */) as isize + error_p as isize } diff --git a/src/framework/scheduler/looper/policy/evolution.rs b/src/framework/scheduler/looper/policy/evolution.rs index a917722..2c6bd7a 100644 --- a/src/framework/scheduler/looper/policy/evolution.rs +++ b/src/framework/scheduler/looper/policy/evolution.rs @@ -23,7 +23,7 @@ use crate::{ cpu_temp_watcher::CpuTempWatcher, framework::scheduler::looper::buffer::Buffer, Config, Mode, }; -use super::PidParams; +use super::ControllerParams; pub const DATABASE_PATH: &str = "/sdcard/Android/fas-rs/database.db"; @@ -53,50 +53,46 @@ impl Fitness { pub fn open_database() -> Result { let conn = Connection::open(DATABASE_PATH)?; conn.execute( - "CREATE TABLE IF NOT EXISTS pid_params ( + "CREATE TABLE IF NOT EXISTS control_params ( id TEXT PRIMARY KEY, - kp REAL NOT NULL, - ki REAL NOT NULL, - kd REAL NOT NULL + kp REAL NOT NULL )", [], )?; Ok(conn) } -pub fn load_pid_params(conn: &Connection, package_name: &str) -> Result { - let mut stmt = conn.prepare("SELECT kp, ki, kd FROM pid_params WHERE id = ?1")?; +pub fn load_control_params(conn: &Connection, package_name: &str) -> Result { + let mut stmt = conn.prepare("SELECT kp, ki, kd FROM control_params WHERE id = ?1")?; let params = stmt.query_row(params![package_name], |row| { - Ok(PidParams { - kp: row.get(0)?, - ki: row.get(1)?, - kd: row.get(2)?, - }) + Ok(ControllerParams { kp: row.get(0)? }) })?; Ok(params) } -pub fn save_pid_params(conn: &Connection, package_name: &str, pid_params: PidParams) -> Result<()> { +pub fn save_control_params( + conn: &Connection, + package_name: &str, + control_params: ControllerParams, +) -> Result<()> { conn.execute( - "INSERT INTO pid_params (id, kp, ki, kd) + "INSERT INTO control_params (id, kp, ki, kd) VALUES (?1, ?2, ?3, ?4) ON CONFLICT(id) DO UPDATE SET kp = excluded.kp, ki = excluded.ki, kd = excluded.kd", - params![package_name, pid_params.kp, pid_params.ki, pid_params.kd,], + params![package_name, control_params.kp], )?; Ok(()) } -pub fn mutate_params(params: PidParams) -> PidParams { +pub fn mutate_params(params: ControllerParams) -> ControllerParams { let mut rng = rand::thread_rng(); - PidParams { + ControllerParams { kp: (params.kp + rng.gen_range(-0.000_1..0.000_1)).clamp(0.000_1, 0.000_8), - ki: (params.ki + rng.gen_range(-0.000_01..0.000_01)).clamp(0.000_015, 0.000_08), - kd: (params.kd + rng.gen_range(-0.000_001..0.000_001)).clamp(0.000_025, 0.000_035), } } diff --git a/src/framework/scheduler/looper/policy/mod.rs b/src/framework/scheduler/looper/policy/mod.rs index f93bda6..0804c04 100644 --- a/src/framework/scheduler/looper/policy/mod.rs +++ b/src/framework/scheduler/looper/policy/mod.rs @@ -16,18 +16,12 @@ pub mod controll; pub mod evolution; #[derive(Debug, Copy, Clone)] -pub struct PidParams { +pub struct ControllerParams { pub kp: f64, - pub ki: f64, - pub kd: f64, } -impl Default for PidParams { +impl Default for ControllerParams { fn default() -> Self { - Self { - kp: 0.000_3, - ki: 0.000_03, - kd: 0.000_003, - } + Self { kp: 0.000_3 } } } diff --git a/src/framework/scheduler/looper/utils.rs b/src/framework/scheduler/looper/utils.rs index c8ac41b..831d675 100644 --- a/src/framework/scheduler/looper/utils.rs +++ b/src/framework/scheduler/looper/utils.rs @@ -20,7 +20,7 @@ use log::info; use super::{ super::FasData, buffer::BufferWorkingState, - policy::evolution::{open_database, save_pid_params}, + policy::evolution::{open_database, save_control_params}, Buffer, Looper, State, }; use crate::{ @@ -43,7 +43,9 @@ impl Looper { .analyzer .detach_app(buffer.package_info.pid); let pkg = buffer.package_info.pkg.clone(); - if save_pid_params(&self.database, &pkg, self.evolution_state.pid_params).is_err() { + if save_control_params(&self.database, &pkg, self.evolution_state.controller_params) + .is_err() + { self.database = open_database().unwrap(); } self.extension