improved wheel handling + tests
This commit is contained in:
parent
6b38c36a28
commit
ea1db833f3
9 changed files with 2318 additions and 13 deletions
|
|
@ -1,14 +1,14 @@
|
|||
|
||||
[target.xtensa-esp32-none-elf]
|
||||
runner = "espflash flash --monitor"
|
||||
|
||||
[build]
|
||||
target = "xtensa-esp32-none-elf"
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Wl,-Tlinkall.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
]
|
||||
|
||||
[build]
|
||||
target = "xtensa-esp32-none-elf"
|
||||
|
||||
[unstable]
|
||||
build-std = ["core", "alloc", "compiler_builtins"]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
fn main() {
|
||||
let target = std::env::var("TARGET").unwrap_or_default();
|
||||
if !target.starts_with("xtensa-") {
|
||||
return;
|
||||
}
|
||||
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
if args.len() > 1 {
|
||||
let kind = &args[1];
|
||||
|
|
|
|||
2187
esp32/host-tests/Cargo.lock
generated
Normal file
2187
esp32/host-tests/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -8,6 +8,7 @@ use esp_hal::time::Rate;
|
|||
use esp_println::println;
|
||||
|
||||
use crate::WHEEL_VALUE;
|
||||
use esp32::{apply_wheel_delta, wheel_delta};
|
||||
|
||||
pub static INPUT: Channel<CriticalSectionRawMutex, u8, 64> = Channel::new();
|
||||
pub static ANGLE: Mutex<CriticalSectionRawMutex, u16> = Mutex::new(0);
|
||||
|
|
@ -34,18 +35,24 @@ pub async fn rotation_read_task(config: RotationConfig) {
|
|||
let old = *locked as i32;
|
||||
*locked = angle;
|
||||
drop(locked);
|
||||
let left_diff = old - angle as i32;
|
||||
let right_diff = angle as i32 - old;
|
||||
let diff = if left_diff.abs() < right_diff.abs() { -left_diff } else { right_diff };
|
||||
let diff = wheel_delta(old, angle as i32, crate::WHEEL_INVERTED);
|
||||
let mut wheel = WHEEL_VALUE.lock().await;
|
||||
if wheel.max != wheel.min {
|
||||
let wheel_range = wheel.max - wheel.min;
|
||||
wheel.value += diff * wheel_range / 4096;
|
||||
if wheel.value < wheel.min {
|
||||
wheel.value = wheel.min;
|
||||
} else if wheel.value > wheel.max {
|
||||
wheel.value = wheel.max;
|
||||
}
|
||||
let min = wheel.min;
|
||||
let max = wheel.max;
|
||||
let mut value = wheel.value;
|
||||
let mut accumulated = wheel.accumulated;
|
||||
let precision = crate::WHEEL_PRECISION;
|
||||
apply_wheel_delta(
|
||||
&mut value,
|
||||
min,
|
||||
max,
|
||||
&mut accumulated,
|
||||
diff,
|
||||
precision,
|
||||
);
|
||||
wheel.value = value;
|
||||
wheel.accumulated = accumulated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
5
esp32/src/lib.rs
Normal file
5
esp32/src/lib.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#![no_std]
|
||||
|
||||
mod wheel;
|
||||
|
||||
pub use wheel::{apply_wheel_delta, wheel_delta};
|
||||
|
|
@ -29,6 +29,8 @@ const WIFI_NETWORK: &str = "flamme";
|
|||
const WIFI_PASSWORD: &str = "12345678";
|
||||
const TARGET_IP: &str = "84.238.32.253";
|
||||
const TARGET_PORT: u16 = 7070;
|
||||
const WHEEL_PRECISION: i32 = 32;
|
||||
const WHEEL_INVERTED: bool = false;
|
||||
|
||||
enum QuestionType {
|
||||
Choice,
|
||||
|
|
@ -47,6 +49,7 @@ struct WheelData {
|
|||
value: i32,
|
||||
min: i32,
|
||||
max: i32,
|
||||
accumulated: i32,
|
||||
}
|
||||
|
||||
static QUESTION: Mutex<CriticalSectionRawMutex, Option<QuestionData>> = Mutex::new(None);
|
||||
|
|
@ -55,6 +58,7 @@ static WHEEL_VALUE: Mutex<CriticalSectionRawMutex, WheelData> = Mutex::new(Wheel
|
|||
value: 0,
|
||||
min: 0,
|
||||
max: 0,
|
||||
accumulated: 0,
|
||||
});
|
||||
|
||||
#[panic_handler]
|
||||
|
|
@ -79,6 +83,7 @@ pub async fn tcp_read_loop(mut read: TcpReader<'_>) {
|
|||
value: 0,
|
||||
min: 0,
|
||||
max: 0,
|
||||
accumulated: 0,
|
||||
};
|
||||
for line in str.lines() {
|
||||
if line == "$$" {
|
||||
|
|
@ -120,6 +125,7 @@ pub async fn tcp_read_loop(mut read: TcpReader<'_>) {
|
|||
if let QuestionType::Numeric { min, max } = q_type {
|
||||
let diff = max - min;
|
||||
future_wheel.value = min + diff / 2;
|
||||
future_wheel.accumulated = 0;
|
||||
}
|
||||
|
||||
question_data = Some(QuestionData {
|
||||
|
|
|
|||
48
esp32/src/wheel.rs
Normal file
48
esp32/src/wheel.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
pub const WHEEL_TICKS: i32 = 4096;
|
||||
|
||||
pub fn wheel_delta(old_angle: i32, current_angle: i32, inverted: bool) -> i32 {
|
||||
let mut diff = current_angle - old_angle;
|
||||
if diff.abs() > WHEEL_TICKS / 2 {
|
||||
diff = if diff > 0 {
|
||||
diff - WHEEL_TICKS
|
||||
} else {
|
||||
diff + WHEEL_TICKS
|
||||
};
|
||||
}
|
||||
|
||||
if inverted {
|
||||
-diff
|
||||
} else {
|
||||
diff
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_wheel_delta(
|
||||
value: &mut i32,
|
||||
min: i32,
|
||||
max: i32,
|
||||
accumulated: &mut i32,
|
||||
diff: i32,
|
||||
precision: i32,
|
||||
) {
|
||||
if max == min || precision <= 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
*accumulated += diff;
|
||||
let step_count = *accumulated / precision;
|
||||
if step_count == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
*accumulated -= step_count * precision;
|
||||
*value += step_count;
|
||||
if *value < min {
|
||||
*value = min;
|
||||
} else if *value > max {
|
||||
*value = max;
|
||||
}
|
||||
if *value == min || *value == max {
|
||||
*accumulated = 0;
|
||||
}
|
||||
}
|
||||
1
esp32/test.sh
Normal file
1
esp32/test.sh
Normal file
|
|
@ -0,0 +1 @@
|
|||
rustc --test wheel-tests.rs -o wheel-tests && ./wheel-tests
|
||||
46
esp32/wheel-tests.rs
Normal file
46
esp32/wheel-tests.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
mod wheel {
|
||||
include!("src/wheel.rs");
|
||||
}
|
||||
|
||||
use wheel::{apply_wheel_delta, wheel_delta};
|
||||
|
||||
#[test]
|
||||
fn wraps_forward_across_zero() {
|
||||
assert_eq!(wheel_delta(4090, 5, false), 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wraps_backward_across_zero() {
|
||||
assert_eq!(wheel_delta(5, 4090, false), -11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inverts_direction() {
|
||||
assert_eq!(wheel_delta(10, 20, true), -10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accumulates_before_applying_selection() {
|
||||
let mut value = 5;
|
||||
let mut accumulated = 0;
|
||||
|
||||
apply_wheel_delta(&mut value, 0, 10, &mut accumulated, 10, 32);
|
||||
assert_eq!(value, 5);
|
||||
assert_eq!(accumulated, 10);
|
||||
|
||||
apply_wheel_delta(&mut value, 0, 10, &mut accumulated, 22, 32);
|
||||
assert_eq!(value, 6);
|
||||
assert_eq!(accumulated, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clamps_and_resets_at_bounds() {
|
||||
let mut value = 10;
|
||||
let mut accumulated = 0;
|
||||
|
||||
apply_wheel_delta(&mut value, 0, 10, &mut accumulated, 64, 32);
|
||||
assert_eq!(value, 10);
|
||||
assert_eq!(accumulated, 0);
|
||||
}
|
||||
Loading…
Reference in a new issue