1use core::ops::Range;
5
6const NANOS_IS_SEC: f32 = 1_000_000_000.0;
7
8pub const EPSILON: f32 = 0.5;
12
13pub fn approx_eq(left: f32, right: f32) -> bool {
15 (left - right).abs() < EPSILON
16}
17
18pub fn duty_to_angle(duty: f32, max_angle: f32, duty_range: &Range<f32>) -> f32 {
20 let clamped_duty = duty.clamp(duty_range.start, duty_range.end);
21 ((clamped_duty - duty_range.start) / (duty_range.end - duty_range.start)) * max_angle
22}
23
24pub fn angle_to_duty(angle: f32, max_angle: f32, duty_range: &Range<f32>) -> f32 {
26 let clamped_angle = angle.clamp(0.0, max_angle);
27 duty_range.start + (clamped_angle / max_angle) * (duty_range.end - duty_range.start)
28}
29
30pub fn calc_duty_range(pulse_width_ns: Range<u32>, frequency_hz: f32, max_duty: f32) -> Range<f32> {
32 pub fn pulse_to_duty(pulse_ns: u32, frequency_hz: f32, max_duty: f32) -> f32 {
33 pulse_ns as f32 * frequency_hz * max_duty / NANOS_IS_SEC
34 }
35
36 let min_pulse = pulse_width_ns.start;
37 let max_pulse = pulse_width_ns.end;
38
39 let min_duty = pulse_to_duty(min_pulse, frequency_hz, max_duty);
41 let max_duty_val = pulse_to_duty(max_pulse, frequency_hz, max_duty);
42
43 let mut min_duty = min_duty.min(max_duty);
45 let mut max_duty_val = max_duty_val.min(max_duty);
46
47 if min_duty >= max_duty_val {
50 let mid = (min_duty + max_duty_val) / 2.0;
51 min_duty = mid.min(max_duty - 1.0);
52 max_duty_val = (min_duty + 1.0).min(max_duty);
53 }
54
55 min_duty..max_duty_val
56}