Reduce noise on coarse detents
This commit is contained in:
@@ -73,13 +73,16 @@ static void HSV_to_RGB(float h, float s, float v, uint8_t *r, uint8_t *g, uint8_
|
||||
}
|
||||
|
||||
void DisplayTask::run() {
|
||||
delay(100);
|
||||
tft_.begin();
|
||||
tft_.invertDisplay(1);
|
||||
tft_.setRotation(0);
|
||||
tft_.fillScreen(TFT_PURPLE);
|
||||
|
||||
spr_.setColorDepth(16);
|
||||
if (spr_.createSprite(TFT_WIDTH, TFT_HEIGHT) == nullptr) {
|
||||
Serial.println("ERROR: sprite allocation failed!");
|
||||
tft_.fillScreen(TFT_RED);
|
||||
}
|
||||
spr_.setTextColor(0xFFFF, TFT_BLACK);
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ static KnobConfig configs[] = {
|
||||
{
|
||||
2,
|
||||
0,
|
||||
45 * PI / 180,
|
||||
60 * PI / 180,
|
||||
1,
|
||||
0.6, // Note the snap point is slightly past the midpoint (0.5); compare to normal detents which use a snap point *past* the next value (i.e. > 1)
|
||||
0.55, // Note the snap point is slightly past the midpoint (0.5); compare to normal detents which use a snap point *past* the next value (i.e. > 1)
|
||||
"On/off\nStrong detent",
|
||||
},
|
||||
{
|
||||
@@ -81,7 +81,7 @@ static KnobConfig configs[] = {
|
||||
32,
|
||||
0,
|
||||
8.225806452 * PI / 180,
|
||||
0.1,
|
||||
0.2,
|
||||
1.1,
|
||||
"Coarse values\nWeak detents",
|
||||
},
|
||||
|
||||
@@ -104,6 +104,25 @@ void MotorTask::run() {
|
||||
if (xQueueReceive(queue_, &config, 0) == pdTRUE) {
|
||||
Serial.println("Got new config");
|
||||
current_detent_center = motor.shaft_angle;
|
||||
|
||||
// Update derivative factor of torque controller based on detent width.
|
||||
// If the D factor is large on coarse detents, the motor ends up making noise because the P&D factors amplify the noise from the sensor.
|
||||
// This is a piecewise linear function so that fine detents (small width) get a higher D factor and coarse detents get a small D factor.
|
||||
// Fine detents need a nonzero D factor to artificially create "clicks" each time a new value is reached (the P factor is small
|
||||
// for fine detents due to the smaller angular errors, and the existing P factor doesn't work well for very small angle changes (easy to
|
||||
// get runaway due to sensor noise & lag)).
|
||||
// TODO: consider eliminating this D factor entirely and just "play" a hardcoded haptic "click" (e.g. a quick burst of torque in each
|
||||
// direction) whenever the position changes when the detent width is too small for the P factor to work well.
|
||||
const float derivative_lower_strength = config.detent_strength_unit * 0.06;
|
||||
const float derivative_upper_strength = config.detent_strength_unit * 0;
|
||||
const float derivative_position_width_lower = 5 * PI / 180;
|
||||
const float derivative_position_width_upper = 10 * PI / 180;
|
||||
const float raw = derivative_lower_strength + (derivative_upper_strength - derivative_lower_strength)/(derivative_position_width_upper - derivative_position_width_lower)*(config.position_width_radians - derivative_position_width_lower);
|
||||
motor.PID_velocity.D = CLAMP(
|
||||
raw,
|
||||
min(derivative_lower_strength, derivative_upper_strength),
|
||||
max(derivative_lower_strength, derivative_upper_strength)
|
||||
);
|
||||
}
|
||||
|
||||
idle_check_velocity_ewma = motor.shaft_velocity * IDLE_VELOCITY_EWMA_ALPHA + idle_check_velocity_ewma * (1 - IDLE_VELOCITY_EWMA_ALPHA);
|
||||
@@ -144,9 +163,10 @@ void MotorTask::run() {
|
||||
fminf(config.position_width_radians*DEAD_ZONE_DETENT_PERCENT, DEAD_ZONE_RAD));
|
||||
|
||||
bool out_of_bounds = config.num_positions > 0 && ((angle_to_detent_center > 0 && config.position == 0) || (angle_to_detent_center < 0 && config.position == config.num_positions - 1));
|
||||
motor.PID_velocity.limit = out_of_bounds ? 10 : 3;
|
||||
motor.PID_velocity.limit = 10; //out_of_bounds ? 10 : 3;
|
||||
motor.PID_velocity.P = out_of_bounds ? 4 : config.detent_strength_unit * 4;
|
||||
motor.PID_velocity.D = config.detent_strength_unit * 0.02;
|
||||
|
||||
|
||||
|
||||
if (fabsf(motor.shaft_velocity) > 20) {
|
||||
// Don't apply torque if velocity is too high (helps avoid positive feedback loop/runaway)
|
||||
|
||||
Reference in New Issue
Block a user