dda.c/.h: move n and c back into the dda structure.

This is a preparation for starting a move from non-zero speeds,
which is needed for look-ahead. Keeping both variables in
move_state and doing the calculations in dda_start() is possible
in principle, but might not fit the tight time budget we have when
going from one movement to the next at high step rates.

To deal with this, we have to pre-calculate n and c, so we have
to move it back into the DDA structure. It was there a year ago
already, but moved into move_state to save RAM (move_state exists
only once, dda as often as there are movement queue entries).
This commit is contained in:
Markus Hitter 2013-10-23 15:46:18 +02:00
parent 4190d6ffb9
commit f0b9daeea0
2 changed files with 18 additions and 24 deletions

35
dda.c
View File

@ -318,7 +318,9 @@ void dda_create(DDA *dda, TARGET *target, DDA *prev_dda) {
calculation. Make sure this does not happen. calculation. Make sure this does not happen.
Note 4: Anyone trying to run their machine at 65535 mm/min > 1m/s is nuts Note 4: Anyone trying to run their machine at 65535 mm/min > 1m/s is nuts
*/ */
if (target->F > 65534) target->F = 65534; if (target->F > 65534)
target->F = 65534;
// Note: this is inaccurate for several reasons: // Note: this is inaccurate for several reasons:
// - target->F isn't reverse-calculated from c_limit, so speed // - target->F isn't reverse-calculated from c_limit, so speed
// reductions due to slow axes are ignored. // reductions due to slow axes are ignored.
@ -328,6 +330,7 @@ void dda_create(DDA *dda, TARGET *target, DDA *prev_dda) {
// equal or larger than the number of steps required for acceleration, // equal or larger than the number of steps required for acceleration,
// so we can use it when also limiting max speed according to c_limit. // so we can use it when also limiting max speed according to c_limit.
dda->rampup_steps = ACCELERATE_RAMP_LEN(target->F); dda->rampup_steps = ACCELERATE_RAMP_LEN(target->F);
// Quick hack: we do not do Z move joins as jerk on the Z axis is undesirable; // Quick hack: we do not do Z move joins as jerk on the Z axis is undesirable;
// as the ramp length is calculated for XY, its incorrect for Z: apply the original // as the ramp length is calculated for XY, its incorrect for Z: apply the original
// 'fix' to simply specify a large enough ramp for any speed. // 'fix' to simply specify a large enough ramp for any speed.
@ -342,6 +345,10 @@ void dda_create(DDA *dda, TARGET *target, DDA *prev_dda) {
#ifdef LOOKAHEAD #ifdef LOOKAHEAD
dda_join_moves(prev_dda, dda); dda_join_moves(prev_dda, dda);
#endif #endif
dda->n = 0;
dda->c = C0;
#elif defined ACCELERATION_TEMPORAL #elif defined ACCELERATION_TEMPORAL
// TODO: limit speed of individual axes to MAXIMUM_FEEDRATE // TODO: limit speed of individual axes to MAXIMUM_FEEDRATE
// TODO: calculate acceleration/deceleration for each axis // TODO: calculate acceleration/deceleration for each axis
@ -425,8 +432,6 @@ void dda_start(DDA *dda) {
move_state.endstop_stop = 0; move_state.endstop_stop = 0;
#ifdef ACCELERATION_RAMPING #ifdef ACCELERATION_RAMPING
move_state.step_no = 0; move_state.step_no = 0;
move_state.n = 0;
move_state.c = C0;
#endif #endif
#ifdef ACCELERATION_TEMPORAL #ifdef ACCELERATION_TEMPORAL
move_state.x_time = move_state.y_time = \ move_state.x_time = move_state.y_time = \
@ -437,11 +442,7 @@ void dda_start(DDA *dda) {
dda->live = 1; dda->live = 1;
// set timeout for first step // set timeout for first step
#ifdef ACCELERATION_RAMPING setTimer(dda->c >> 8);
setTimer(move_state.c >> 8);
#else
setTimer(dda->c >> 8);
#endif
} }
// else just a speed change, keep dda->live = 0 // else just a speed change, keep dda->live = 0
@ -618,7 +619,7 @@ void dda_step(DDA *dda) {
if ((move_state.x_steps == 0 && move_state.y_steps == 0 && if ((move_state.x_steps == 0 && move_state.y_steps == 0 &&
move_state.z_steps == 0 && move_state.e_steps == 0) move_state.z_steps == 0 && move_state.e_steps == 0)
#ifdef ACCELERATION_RAMPING #ifdef ACCELERATION_RAMPING
|| (move_state.endstop_stop && move_state.n == 0) || (move_state.endstop_stop && dda->n == 0)
#endif #endif
) { ) {
dda->live = 0; dda->live = 0;
@ -636,11 +637,7 @@ void dda_step(DDA *dda) {
else else
psu_timeout = 0; psu_timeout = 0;
#ifdef ACCELERATION_RAMPING setTimer(dda->c >> 8);
setTimer(move_state.c >> 8);
#else
setTimer(dda->c >> 8);
#endif
// turn off step outputs, hopefully they've been on long enough by now to register with the drivers // turn off step outputs, hopefully they've been on long enough by now to register with the drivers
// if not, too bad. or insert a (very!) small delay here, or fire up a spare timer or something. // if not, too bad. or insert a (very!) small delay here, or fire up a spare timer or something.
@ -786,20 +783,20 @@ void dda_clock() {
recalc_speed = 0; recalc_speed = 0;
if (move_step_no < dda->rampup_steps) { if (move_step_no < dda->rampup_steps) {
move_state.n = move_step_no; dda->n = move_step_no;
recalc_speed = 1; recalc_speed = 1;
} }
else if (move_step_no >= dda->rampdown_steps) { else if (move_step_no >= dda->rampdown_steps) {
move_state.n = dda->total_steps - move_step_no; dda->n = dda->total_steps - move_step_no;
recalc_speed = 1; recalc_speed = 1;
} }
if (recalc_speed) { if (recalc_speed) {
if (move_state.n == 0) if (dda->n == 0)
move_c = C0; move_c = C0;
else else
// Explicit formula: sqrt(n + 1) - sqrt(n), // Explicit formula: sqrt(n + 1) - sqrt(n),
// approximation here: 1 / (2 * sqrt(n)). // approximation here: 1 / (2 * sqrt(n)).
move_c = ((C0 >> 8) * int_inv_sqrt(move_state.n)) >> 5; move_c = ((C0 >> 8) * int_inv_sqrt(dda->n)) >> 5;
if (move_c < dda->c_min) { if (move_c < dda->c_min) {
// We hit max speed not always exactly. // We hit max speed not always exactly.
@ -816,7 +813,7 @@ void dda_clock() {
// Write results. // Write results.
ATOMIC_START ATOMIC_START
move_state.c = move_c; dda->c = move_c;
ATOMIC_END ATOMIC_END
} }
#endif #endif

7
dda.h
View File

@ -72,10 +72,6 @@ typedef struct {
#ifdef ACCELERATION_RAMPING #ifdef ACCELERATION_RAMPING
/// counts actual steps done /// counts actual steps done
uint32_t step_no; uint32_t step_no;
/// time until next step
uint32_t c;
/// tracking variable
int32_t n;
#endif #endif
#ifdef ACCELERATION_TEMPORAL #ifdef ACCELERATION_TEMPORAL
uint32_t x_time; ///< time of the last x step uint32_t x_time; ///< time of the last x step
@ -136,9 +132,10 @@ typedef struct {
#ifdef ACCELERATION_REPRAP #ifdef ACCELERATION_REPRAP
uint32_t end_c; ///< time between 2nd last step and last step uint32_t end_c; ///< time between 2nd last step and last step
int32_t n; ///< precalculated step time offset variable. At every step we calculate \f$c = c - (2 c / n)\f$; \f$n+=4\f$. See http://www.embedded.com/columns/technicalinsights/56800129?printable=true for full description
#endif #endif
#ifdef ACCELERATION_RAMPING #ifdef ACCELERATION_RAMPING
/// precalculated step time offset variable
int32_t n;
/// number of steps accelerating /// number of steps accelerating
uint32_t rampup_steps; uint32_t rampup_steps;
/// number of last step before decelerating /// number of last step before decelerating