diff --git a/firmware/film-scanner-fw/.cargo/config.toml b/firmware/film-scanner-fw/.cargo/config.toml index dc027bf..774199e 100644 --- a/firmware/film-scanner-fw/.cargo/config.toml +++ b/firmware/film-scanner-fw/.cargo/config.toml @@ -20,7 +20,7 @@ rustflags = [ ] [build] -target = "thumbv6m-none-eabi" +target = "thumbv7em-none-eabihf" [env] -DEFMT_LOG = "debug" \ No newline at end of file +DEFMT_LOG = "debug" diff --git a/firmware/jerk_control/src/bin/sqrt_test.rs b/firmware/jerk_control/src/bin/sqrt_test.rs new file mode 100644 index 0000000..a4f791a --- /dev/null +++ b/firmware/jerk_control/src/bin/sqrt_test.rs @@ -0,0 +1,36 @@ +fn ulp(f: f32) -> f32 { + f32::from_bits((f.to_bits() & 0x7f80_0000) - 0x0b80_0000) +} + +fn fn_err(actual: f32, calc: f32) -> f32 { + (calc - actual).abs() / actual +} + + +fn test_all(fname: &str, actual: fn(f32) -> f32, calc: fn(f32) -> f32) { + let mut max_err = 0f32; + let mut max_err_value = 0f32; + for i in (0x00c0_0000..0x0f7f_ffffu32).map(f32::from_bits) { + // range of normalized floats... + let err = fn_err(actual(i), calc(i)); + if err > max_err { + max_err = err; + max_err_value = i; + } + } + + let max_err_pct = max_err * 100f32; + println!("{}: {}% @ {}", fname, max_err_pct, max_err_value); + println!( + "Value: 0x{:08x}\n + Calculated: 0x{:08x}\n + Actual: 0x{:08x}", + max_err_value.to_bits(), + calc(max_err_value).to_bits(), actual(max_err_value).to_bits()) +} + + +fn main() { + // test_all("sqrt", f32::sqrt, jerk_control::math_ext::Roots::sqrt); + test_all("cbrt", f32::cbrt, jerk_control::math_ext::Roots::cbrt); +} \ No newline at end of file diff --git a/firmware/jerk_control/src/lib.rs b/firmware/jerk_control/src/lib.rs index 52987a0..d2f90d3 100644 --- a/firmware/jerk_control/src/lib.rs +++ b/firmware/jerk_control/src/lib.rs @@ -1,2 +1,6 @@ +// #![no_std] + pub mod planner; -pub mod executor; \ No newline at end of file +pub mod executor; + +pub mod math_ext; diff --git a/firmware/jerk_control/src/planner.rs b/firmware/jerk_control/src/planner.rs index 6da8f9d..f413e9c 100644 --- a/firmware/jerk_control/src/planner.rs +++ b/firmware/jerk_control/src/planner.rs @@ -4,6 +4,7 @@ //! All of their derivations can be found in the motion-control.ipynb file. use core::num::Wrapping; +use core::option::Option; pub struct Config { /// Max jerk, in mm/s^3 @@ -162,7 +163,7 @@ impl Planner { .clamp(0.0, (1u32 << 31) as f32); let step_size = config.step_size * 6. * tick_rate * tick_rate * tick_rate / config.j_max; if step_size > (u32::MAX / 2) as f32 { - eprintln!("Failed to configure planner: stepsize = {}", step_size); + //eprintln!("Failed to configure planner: stepsize = {}", step_size); return false; } self.a_max = a_max as u32; @@ -212,7 +213,7 @@ impl Planner { let tv = (dx - ramp_dx) * 2 / s4v as u64; let tv = ((tv + 1) / 2) as u32; - eprintln!("ta={ta}, tj={tj}, tv={tv}"); + //eprintln!("ta={ta}, tj={tj}, tv={tv}"); let j_real = dir * 6; let mut segments = [Segment::default(); 8]; let seg_params = [ diff --git a/firmware/motion-tester/Cargo.toml b/firmware/motion-tester/Cargo.toml index 1e48dda..0f942f8 100644 --- a/firmware/motion-tester/Cargo.toml +++ b/firmware/motion-tester/Cargo.toml @@ -7,4 +7,6 @@ edition = "2021" [dependencies] jerk_control = { path = "../jerk_control" } -structopt = { version = "0.3.26" } \ No newline at end of file +# structopt = { version = "0.3.26" } + +rayon = "1.5.2" \ No newline at end of file diff --git a/firmware/motion-tester/src/bin/math_test.rs b/firmware/motion-tester/src/bin/math_test.rs new file mode 100644 index 0000000..913f080 --- /dev/null +++ b/firmware/motion-tester/src/bin/math_test.rs @@ -0,0 +1,47 @@ +use rayon::prelude::*; + +fn ulp(f: f32) -> f32 { + f32::from_bits((f.to_bits() & 0x7f80_0000) - 0x0b80_0000) +} + +fn fn_err(actual: f32, calc: f32) -> f32 { + (calc - actual).abs() / actual +} + + +fn test_all(fname: &str, actual: fn(f32) -> f32, calc: fn(f32) -> f32) { + let mut max_err = 0f32; + let mut max_err_value = 0f32; + (0x01..=0xfe).into_par_iter() + .map(|exp| { + (0x0..=0x7f_ffff).map(|mant| f32::from_bits((exp << 23) + mant)) + .max_by_key(|value| fn_err(actual(*value), calc(*value)).to_bits()) + .unwrap() + }) + .map(|value| (value,fn_err(actual(value), calc(value)))) + .collect::>(); + + for i in (0x0400_0000..0x0f7f_ffffu32).map(f32::from_bits) { + // range of normalized floats... + let err = fn_err(actual(i), calc(i)); + if err > max_err { + max_err = err; + max_err_value = i; + } + } + + let max_err_pct = max_err * 100f32; + println!("{}: {}% @ {}", fname, max_err_pct, max_err_value); + println!( + "Value: 0x{:08x}\n + Calculated: 0x{:08x}\n + Actual: 0x{:08x}", + max_err_value.to_bits(), + calc(max_err_value).to_bits(), actual(max_err_value).to_bits()) +} + + +fn main() { + // test_all("sqrt", f32::sqrt, jerk_control::math_ext::Roots::sqrt); + test_all("cbrt", f32::cbrt, jerk_control::math_ext::Roots::cbrt); +} \ No newline at end of file