itersolve: Enhance "false position" method with "illinois algorithm"

This prevents some cases where the iterative solver fails to converge
in a reasonable time, causing "no next step" errors.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2020-08-07 19:36:55 -04:00
parent e5a3fd7cee
commit 513582afc4
1 changed files with 8 additions and 1 deletions

View File

@ -22,7 +22,7 @@ struct timepos {
double time, position; double time, position;
}; };
// Find step using "false position" method // Find step using "false position" method (with "Illinois algorithm")
static struct timepos static struct timepos
itersolve_find_step(struct stepper_kinematics *sk, struct move *m itersolve_find_step(struct stepper_kinematics *sk, struct move *m
, struct timepos low, struct timepos high , struct timepos low, struct timepos high
@ -39,6 +39,7 @@ itersolve_find_step(struct stepper_kinematics *sk, struct move *m
if (high_sign == signbit(low.position)) if (high_sign == signbit(low.position))
// The target is not in the low/high range - return low range // The target is not in the low/high range - return low range
return (struct timepos){ low.time, target }; return (struct timepos){ low.time, target };
int prev_choice = 0;
for (;;) { for (;;) {
double guess_time = ((low.time*high.position - high.time*low.position) double guess_time = ((low.time*high.position - high.time*low.position)
/ (high.position - low.position)); / (high.position - low.position));
@ -51,9 +52,15 @@ itersolve_find_step(struct stepper_kinematics *sk, struct move *m
if (guess_sign == high_sign) { if (guess_sign == high_sign) {
high.time = guess_time; high.time = guess_time;
high.position = guess_position; high.position = guess_position;
if (prev_choice > 0)
low.position *= .5;
prev_choice = 1;
} else { } else {
low.time = guess_time; low.time = guess_time;
low.position = guess_position; low.position = guess_position;
if (prev_choice < 0)
high.position *= .5;
prev_choice = -1;
} }
} }
return best_guess; return best_guess;