forked from NaxdyOrg/NaxGCC-FW
feat: finish notch remap
This commit is contained in:
parent
0f11c659c4
commit
1861b89505
3 changed files with 124 additions and 55 deletions
|
@ -112,6 +112,8 @@ pub struct StickConfig {
|
||||||
#[packed_field(size_bits = "8")]
|
#[packed_field(size_bits = "8")]
|
||||||
pub y_snapback: i8, // not used for CStick
|
pub y_snapback: i8, // not used for CStick
|
||||||
#[packed_field(size_bits = "8")]
|
#[packed_field(size_bits = "8")]
|
||||||
|
pub cardinal_snapping: i8, // not used for CStick
|
||||||
|
#[packed_field(size_bits = "8")]
|
||||||
pub x_smoothing: u8,
|
pub x_smoothing: u8,
|
||||||
#[packed_field(size_bits = "8")]
|
#[packed_field(size_bits = "8")]
|
||||||
pub y_smoothing: u8,
|
pub y_smoothing: u8,
|
||||||
|
@ -132,7 +134,8 @@ impl Default for StickConfig {
|
||||||
y_snapback: 0,
|
y_snapback: 0,
|
||||||
x_smoothing: 0,
|
x_smoothing: 0,
|
||||||
y_smoothing: 0,
|
y_smoothing: 0,
|
||||||
analog_scaler: 0,
|
cardinal_snapping: 0,
|
||||||
|
analog_scaler: 100,
|
||||||
temp_cal_points_x: *DEFAULT_CAL_POINTS_X.to_packed_float_array(),
|
temp_cal_points_x: *DEFAULT_CAL_POINTS_X.to_packed_float_array(),
|
||||||
temp_cal_points_y: *DEFAULT_CAL_POINTS_Y.to_packed_float_array(),
|
temp_cal_points_y: *DEFAULT_CAL_POINTS_Y.to_packed_float_array(),
|
||||||
angles: *DEFAULT_ANGLES.to_packed_float_array(),
|
angles: *DEFAULT_ANGLES.to_packed_float_array(),
|
||||||
|
@ -147,9 +150,9 @@ pub struct ControllerConfig {
|
||||||
pub config_revision: u8,
|
pub config_revision: u8,
|
||||||
#[packed_field(size_bits = "8")]
|
#[packed_field(size_bits = "8")]
|
||||||
pub config_version: u8,
|
pub config_version: u8,
|
||||||
#[packed_field(size_bytes = "327")]
|
#[packed_field(size_bytes = "328")]
|
||||||
pub astick_config: StickConfig,
|
pub astick_config: StickConfig,
|
||||||
#[packed_field(size_bytes = "327")]
|
#[packed_field(size_bytes = "328")]
|
||||||
pub cstick_config: StickConfig,
|
pub cstick_config: StickConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +171,7 @@ impl ControllerConfig {
|
||||||
pub fn from_flash_memory(
|
pub fn from_flash_memory(
|
||||||
mut flash: &mut Flash<'static, FLASH, Async, FLASH_SIZE>,
|
mut flash: &mut Flash<'static, FLASH, Async, FLASH_SIZE>,
|
||||||
) -> Result<Self, embassy_rp::flash::Error> {
|
) -> Result<Self, embassy_rp::flash::Error> {
|
||||||
let mut controller_config_packed: <ControllerConfig as packed_struct::PackedStruct>::ByteArray = [0u8; 656]; // ControllerConfig byte size
|
let mut controller_config_packed: <ControllerConfig as packed_struct::PackedStruct>::ByteArray = [0u8; 658]; // ControllerConfig byte size
|
||||||
flash.blocking_read(ADDR_OFFSET, &mut controller_config_packed)?;
|
flash.blocking_read(ADDR_OFFSET, &mut controller_config_packed)?;
|
||||||
|
|
||||||
match ControllerConfig::unpack(&controller_config_packed).unwrap() {
|
match ControllerConfig::unpack(&controller_config_packed).unwrap() {
|
||||||
|
|
133
src/input.rs
133
src/input.rs
|
@ -1,4 +1,4 @@
|
||||||
use defmt::{debug, info};
|
use defmt::{debug, info, trace, Format};
|
||||||
use embassy_futures::{join::join, yield_now};
|
use embassy_futures::{join::join, yield_now};
|
||||||
use embassy_rp::{
|
use embassy_rp::{
|
||||||
flash::{Async, Flash},
|
flash::{Async, Flash},
|
||||||
|
@ -45,7 +45,7 @@ struct StickPositions {
|
||||||
cy: f32,
|
cy: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default, Format)]
|
||||||
struct RawStickValues {
|
struct RawStickValues {
|
||||||
a_linearized: XyValuePair<f32>,
|
a_linearized: XyValuePair<f32>,
|
||||||
c_linearized: XyValuePair<f32>,
|
c_linearized: XyValuePair<f32>,
|
||||||
|
@ -182,8 +182,7 @@ async fn update_stick_states<
|
||||||
y: (cy_sum as f32) / (adc_count as f32) / 4096.0f32,
|
y: (cy_sum as f32) / (adc_count as f32) / 4096.0f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Raw Control Stick: {:?}", raw_controlstick);
|
trace!("Raw Control Stick: {}", raw_controlstick);
|
||||||
debug!("Raw C Stick: {:?}", raw_cstick);
|
|
||||||
|
|
||||||
raw_stick_values.a_raw = raw_controlstick;
|
raw_stick_values.a_raw = raw_controlstick;
|
||||||
raw_stick_values.c_raw = raw_cstick;
|
raw_stick_values.c_raw = raw_cstick;
|
||||||
|
@ -199,107 +198,145 @@ async fn update_stick_states<
|
||||||
raw_stick_values.c_linearized.x = pos_cx;
|
raw_stick_values.c_linearized.x = pos_cx;
|
||||||
raw_stick_values.c_linearized.y = pos_cy;
|
raw_stick_values.c_linearized.y = pos_cy;
|
||||||
|
|
||||||
|
trace!("Raw Stick Values 001: {:?}", raw_stick_values);
|
||||||
|
|
||||||
let (x_pos_filt, y_pos_filt) =
|
let (x_pos_filt, y_pos_filt) =
|
||||||
kalman_state.run_kalman(x_z, y_z, &controller_config.astick_config, &filter_gains);
|
kalman_state.run_kalman(x_z, y_z, &controller_config.astick_config, &filter_gains);
|
||||||
|
|
||||||
let (shaped_x, shaped_y) = run_waveshaping(
|
let shaped_astick = match run_waveshaping(
|
||||||
x_pos_filt,
|
x_pos_filt,
|
||||||
y_pos_filt,
|
y_pos_filt,
|
||||||
controller_config.astick_config.x_waveshaping,
|
controller_config.astick_config.x_waveshaping,
|
||||||
controller_config.astick_config.y_waveshaping,
|
controller_config.astick_config.y_waveshaping,
|
||||||
controlstick_waveshaping_values,
|
controlstick_waveshaping_values,
|
||||||
&filter_gains,
|
&filter_gains,
|
||||||
);
|
) {
|
||||||
|
(x, y) => XyValuePair { x, y },
|
||||||
|
};
|
||||||
|
|
||||||
let pos_x: f32 =
|
trace!("Shaped Controlstick: {}", shaped_astick);
|
||||||
filter_gains.smoothing.x * shaped_x + (1.0 - filter_gains.smoothing.x) * old_stick_pos.x;
|
|
||||||
let pos_y =
|
let pos_x: f32 = filter_gains.smoothing.x * shaped_astick.x
|
||||||
filter_gains.smoothing.y * shaped_y + (1.0 - filter_gains.smoothing.y) * old_stick_pos.y;
|
+ (1.0 - filter_gains.smoothing.x) * old_stick_pos.x;
|
||||||
|
let pos_y = filter_gains.smoothing.y * shaped_astick.y
|
||||||
|
+ (1.0 - filter_gains.smoothing.y) * old_stick_pos.y;
|
||||||
old_stick_pos.x = pos_x;
|
old_stick_pos.x = pos_x;
|
||||||
old_stick_pos.y = pos_y;
|
old_stick_pos.y = pos_y;
|
||||||
|
|
||||||
let (shaped_cx, shaped_cy) = run_waveshaping(
|
let shaped_cstick = match run_waveshaping(
|
||||||
pos_cx,
|
pos_cx,
|
||||||
pos_cy,
|
pos_cy,
|
||||||
controller_config.cstick_config.x_waveshaping,
|
controller_config.cstick_config.x_waveshaping,
|
||||||
controller_config.cstick_config.y_waveshaping,
|
controller_config.cstick_config.y_waveshaping,
|
||||||
cstick_waveshaping_values,
|
cstick_waveshaping_values,
|
||||||
&filter_gains,
|
&filter_gains,
|
||||||
);
|
) {
|
||||||
|
(x, y) => XyValuePair { x, y },
|
||||||
|
};
|
||||||
|
|
||||||
let old_cx_pos = old_stick_pos.cx;
|
let old_c_pos = XyValuePair {
|
||||||
let old_cy_pos = old_stick_pos.cy;
|
x: old_stick_pos.cx,
|
||||||
old_stick_pos.cx = shaped_cx;
|
y: old_stick_pos.cy,
|
||||||
old_stick_pos.cy = shaped_cy;
|
};
|
||||||
|
old_stick_pos.cx = shaped_cstick.x;
|
||||||
|
old_stick_pos.cy = shaped_cstick.y;
|
||||||
|
|
||||||
let x_weight_1 = filter_gains.c_smoothing.x;
|
let x_weight_1 = filter_gains.c_smoothing.x;
|
||||||
let x_weight_2 = 1.0 - x_weight_1;
|
let x_weight_2 = 1.0 - x_weight_1;
|
||||||
let y_weight_1 = filter_gains.c_smoothing.y;
|
let y_weight_1 = filter_gains.c_smoothing.y;
|
||||||
let y_weight_2 = 1.0 - y_weight_1;
|
let y_weight_2 = 1.0 - y_weight_1;
|
||||||
|
|
||||||
let pos_cx_filt = x_weight_1 * shaped_cx + x_weight_2 * old_cx_pos;
|
let pos_cx_filt = x_weight_1 * shaped_cstick.x + x_weight_2 * old_c_pos.x;
|
||||||
let pos_cy_filt = y_weight_1 * shaped_cy + y_weight_2 * old_cy_pos;
|
let pos_cy_filt = y_weight_1 * shaped_cstick.y + y_weight_2 * old_c_pos.y;
|
||||||
|
|
||||||
// phob optionally runs a median filter here, but we leave it for now
|
// phob optionally runs a median filter here, but we leave it for now
|
||||||
|
|
||||||
let (mut remapped_x, mut remapped_y) = notch_remap(
|
trace!("Controlstick position: {}, {}", pos_x, pos_y);
|
||||||
|
|
||||||
|
let mut remapped = match notch_remap(
|
||||||
pos_x,
|
pos_x,
|
||||||
pos_y,
|
pos_y,
|
||||||
controlstick_params,
|
controlstick_params,
|
||||||
controller_config,
|
controller_config,
|
||||||
Stick::ControlStick,
|
Stick::ControlStick,
|
||||||
);
|
false,
|
||||||
let (mut remapped_cx, mut remapped_cy) = notch_remap(
|
) {
|
||||||
|
(x, y) => XyValuePair { x, y },
|
||||||
|
};
|
||||||
|
let mut remapped_c = match notch_remap(
|
||||||
pos_cx_filt,
|
pos_cx_filt,
|
||||||
pos_cy_filt,
|
pos_cy_filt,
|
||||||
cstick_params,
|
cstick_params,
|
||||||
controller_config,
|
controller_config,
|
||||||
Stick::CStick,
|
Stick::CStick,
|
||||||
);
|
false,
|
||||||
let (remapped_x_unfiltered, remapped_y_unfiltered) = notch_remap(
|
) {
|
||||||
|
(x, y) => XyValuePair { x, y },
|
||||||
|
};
|
||||||
|
let remapped_unfiltered = match notch_remap(
|
||||||
raw_stick_values.a_linearized.x,
|
raw_stick_values.a_linearized.x,
|
||||||
raw_stick_values.a_linearized.y,
|
raw_stick_values.a_linearized.y,
|
||||||
controlstick_params,
|
controlstick_params,
|
||||||
controller_config,
|
controller_config,
|
||||||
Stick::ControlStick,
|
Stick::ControlStick,
|
||||||
);
|
false,
|
||||||
let (remapped_cx_unfiltered, remapped_cy_unfiltered) = notch_remap(
|
) {
|
||||||
|
(x, y) => XyValuePair { x, y },
|
||||||
|
};
|
||||||
|
let remapped_c_unfiltered = match notch_remap(
|
||||||
raw_stick_values.c_linearized.x,
|
raw_stick_values.c_linearized.x,
|
||||||
raw_stick_values.c_linearized.y,
|
raw_stick_values.c_linearized.y,
|
||||||
cstick_params,
|
cstick_params,
|
||||||
controller_config,
|
controller_config,
|
||||||
Stick::CStick,
|
Stick::CStick,
|
||||||
);
|
false,
|
||||||
|
) {
|
||||||
|
(x, y) => XyValuePair { x, y },
|
||||||
|
};
|
||||||
|
|
||||||
remapped_x = fminf(125., fmaxf(-125., remapped_x));
|
trace!("Remapped Control Stick: {}", remapped);
|
||||||
remapped_y = fminf(125., fmaxf(-125., remapped_y));
|
|
||||||
remapped_cx = fminf(125., fmaxf(-125., remapped_cx));
|
remapped = XyValuePair {
|
||||||
remapped_cy = fminf(125., fmaxf(-125., remapped_cy));
|
x: fminf(125., fmaxf(-125., remapped.x)),
|
||||||
raw_stick_values.a_unfiltered.x = fminf(125., fmaxf(-125., remapped_x_unfiltered));
|
y: fminf(125., fmaxf(-125., remapped.y)),
|
||||||
raw_stick_values.a_unfiltered.y = fminf(125., fmaxf(-125., remapped_y_unfiltered));
|
};
|
||||||
raw_stick_values.c_unfiltered.x = fminf(125., fmaxf(-125., remapped_cx_unfiltered));
|
remapped_c = XyValuePair {
|
||||||
raw_stick_values.c_unfiltered.y = fminf(125., fmaxf(-125., remapped_cy_unfiltered));
|
x: fminf(125., fmaxf(-125., remapped_c.x)),
|
||||||
|
y: fminf(125., fmaxf(-125., remapped_c.y)),
|
||||||
|
};
|
||||||
|
raw_stick_values.a_unfiltered.x = fminf(125., fmaxf(-125., remapped_unfiltered.x));
|
||||||
|
raw_stick_values.a_unfiltered.y = fminf(125., fmaxf(-125., remapped_unfiltered.y));
|
||||||
|
raw_stick_values.c_unfiltered.x = fminf(125., fmaxf(-125., remapped_c_unfiltered.x));
|
||||||
|
raw_stick_values.c_unfiltered.y = fminf(125., fmaxf(-125., remapped_c_unfiltered.y));
|
||||||
|
|
||||||
let mut out_stick_state = current_stick_state.clone();
|
let mut out_stick_state = current_stick_state.clone();
|
||||||
|
|
||||||
let diff_x = (remapped_x + FLOAT_ORIGIN) - current_stick_state.ax as f32;
|
let diff_x = (remapped.x + FLOAT_ORIGIN) - current_stick_state.ax as f32;
|
||||||
if (diff_x > (1.0 + STICK_HYST_VAL)) || (diff_x < -STICK_HYST_VAL) {
|
if (diff_x > (1.0 + STICK_HYST_VAL)) || (diff_x < -STICK_HYST_VAL) {
|
||||||
out_stick_state.ax = (remapped_x + FLOAT_ORIGIN) as u8;
|
out_stick_state.ax = (remapped.x + FLOAT_ORIGIN) as u8;
|
||||||
}
|
}
|
||||||
let diff_y = (remapped_y + FLOAT_ORIGIN) - current_stick_state.ay as f32;
|
let diff_y = (remapped.y + FLOAT_ORIGIN) - current_stick_state.ay as f32;
|
||||||
if (diff_y > (1.0 + STICK_HYST_VAL)) || (diff_y < -STICK_HYST_VAL) {
|
if (diff_y > (1.0 + STICK_HYST_VAL)) || (diff_y < -STICK_HYST_VAL) {
|
||||||
out_stick_state.ay = (remapped_y + FLOAT_ORIGIN) as u8;
|
out_stick_state.ay = (remapped.y + FLOAT_ORIGIN) as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
let diff_cx = (remapped_cx + FLOAT_ORIGIN) - current_stick_state.cx as f32;
|
let diff_cx = (remapped_c.x + FLOAT_ORIGIN) - current_stick_state.cx as f32;
|
||||||
if (diff_cx > (1.0 + STICK_HYST_VAL)) || (diff_cx < -STICK_HYST_VAL) {
|
if (diff_cx > (1.0 + STICK_HYST_VAL)) || (diff_cx < -STICK_HYST_VAL) {
|
||||||
out_stick_state.cx = (remapped_cx + FLOAT_ORIGIN) as u8;
|
out_stick_state.cx = (remapped_c.x + FLOAT_ORIGIN) as u8;
|
||||||
}
|
}
|
||||||
let diff_cy = (remapped_cy + FLOAT_ORIGIN) - current_stick_state.cy as f32;
|
let diff_cy = (remapped_c.y + FLOAT_ORIGIN) - current_stick_state.cy as f32;
|
||||||
if (diff_cy > (1.0 + STICK_HYST_VAL)) || (diff_cy < -STICK_HYST_VAL) {
|
if (diff_cy > (1.0 + STICK_HYST_VAL)) || (diff_cy < -STICK_HYST_VAL) {
|
||||||
out_stick_state.cy = (remapped_cy + FLOAT_ORIGIN) as u8;
|
out_stick_state.cy = (remapped_c.y + FLOAT_ORIGIN) as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!(
|
||||||
|
"Control stick: {}, {}, C-stick: {}, {}",
|
||||||
|
out_stick_state.ax,
|
||||||
|
out_stick_state.ay,
|
||||||
|
out_stick_state.cx,
|
||||||
|
out_stick_state.cy
|
||||||
|
);
|
||||||
|
|
||||||
out_stick_state
|
out_stick_state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +440,7 @@ pub async fn input_loop(
|
||||||
let mut last_loop_time = Instant::now();
|
let mut last_loop_time = Instant::now();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let timer = Timer::after_millis(1);
|
let timer = Timer::after_micros(1000);
|
||||||
|
|
||||||
current_stick_state = update_stick_states(
|
current_stick_state = update_stick_states(
|
||||||
&mut spi,
|
&mut spi,
|
||||||
|
@ -424,10 +461,12 @@ pub async fn input_loop(
|
||||||
|
|
||||||
timer.await;
|
timer.await;
|
||||||
|
|
||||||
debug!(
|
match (Instant::now() - last_loop_time).as_micros() {
|
||||||
"Loop took {} us",
|
a if a > 1100 => {
|
||||||
(Instant::now() - last_loop_time).as_micros()
|
debug!("Loop took {} us", a);
|
||||||
);
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
|
||||||
last_loop_time = Instant::now();
|
last_loop_time = Instant::now();
|
||||||
|
|
||||||
|
|
35
src/stick.rs
35
src/stick.rs
|
@ -3,7 +3,7 @@
|
||||||
use core::f32::consts::PI;
|
use core::f32::consts::PI;
|
||||||
|
|
||||||
use defmt::{debug, Format};
|
use defmt::{debug, Format};
|
||||||
use libm::{atan2f, cosf, fabs, roundf, sinf, sqrtf};
|
use libm::{atan2f, cosf, fabs, fabsf, roundf, sinf, sqrtf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{ControllerConfig, StickConfig, DEFAULT_NOTCH_STATUS},
|
config::{ControllerConfig, StickConfig, DEFAULT_NOTCH_STATUS},
|
||||||
|
@ -583,6 +583,7 @@ pub fn notch_remap(
|
||||||
stick_params: &StickParams,
|
stick_params: &StickParams,
|
||||||
controller_config: &ControllerConfig,
|
controller_config: &ControllerConfig,
|
||||||
which_stick: Stick,
|
which_stick: Stick,
|
||||||
|
is_calibrating: bool,
|
||||||
) -> (f32, f32) {
|
) -> (f32, f32) {
|
||||||
//determine the angle between the x unit vector and the current position vector
|
//determine the angle between the x unit vector and the current position vector
|
||||||
let angle = match atan2f(y_in, x_in) {
|
let angle = match atan2f(y_in, x_in) {
|
||||||
|
@ -608,14 +609,40 @@ pub fn notch_remap(
|
||||||
Stick::CStick => controller_config.cstick_config.analog_scaler as f32 / 100.,
|
Stick::CStick => controller_config.cstick_config.analog_scaler as f32 / 100.,
|
||||||
};
|
};
|
||||||
|
|
||||||
let x_out = stick_scale
|
let mut x_out = stick_scale
|
||||||
* (stick_params.affine_coeffs[region][0] * x_in
|
* (stick_params.affine_coeffs[region][0] * x_in
|
||||||
+ stick_params.affine_coeffs[region][1] * y_in);
|
+ stick_params.affine_coeffs[region][1] * y_in);
|
||||||
let y_out = stick_scale
|
let mut y_out = stick_scale
|
||||||
* (stick_params.affine_coeffs[region][2] * x_in
|
* (stick_params.affine_coeffs[region][2] * x_in
|
||||||
+ stick_params.affine_coeffs[region][3] * y_in);
|
+ stick_params.affine_coeffs[region][3] * y_in);
|
||||||
|
|
||||||
// TODO: here, add calibration step shenanigans
|
if !is_calibrating {
|
||||||
|
let stick_config = match which_stick {
|
||||||
|
Stick::ControlStick => &controller_config.astick_config,
|
||||||
|
Stick::CStick => &controller_config.cstick_config,
|
||||||
|
};
|
||||||
|
|
||||||
|
if stick_config.cardinal_snapping > 0 {
|
||||||
|
if fabsf(x_out) < stick_config.cardinal_snapping as f32 + 0.5 && fabsf(y_out) >= 79.5 {
|
||||||
|
x_out = 0.;
|
||||||
|
}
|
||||||
|
if fabsf(y_out) < stick_config.cardinal_snapping as f32 + 0.5 && fabsf(x_out) >= 79.5 {
|
||||||
|
y_out = 0.;
|
||||||
|
}
|
||||||
|
} else if stick_config.cardinal_snapping == -1 {
|
||||||
|
if fabsf(x_out) < 6.5 && fabsf(y_out) >= 79.5 {
|
||||||
|
x_out = 0.;
|
||||||
|
}
|
||||||
|
if fabsf(y_out) < 6.5 && fabsf(x_out) >= 79.5 {
|
||||||
|
y_out = 0.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if fabsf(x_out) < 3. && fabsf(y_out) < 3. {
|
||||||
|
x_out = 0.;
|
||||||
|
y_out = 0.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(x_out, y_out)
|
(x_out, y_out)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue