Implement acceleration ramping. Enjoy always smooth rides!

This commit is contained in:
Markus Hitter 2010-09-10 02:07:50 +02:00
parent 639f5237be
commit 2178ff4ac1
3 changed files with 77 additions and 0 deletions

40
dda.c
View File

@ -270,9 +270,19 @@ void dda_create(DDA *dda, TARGET *target) {
}
else
dda->accel = 0;
#else // #elifdef isn't valid for gcc
#ifdef ACCELERATION_RAMPING
dda->ramp_steps = dda->total_steps / 2;
dda->step_no = 0;
// c is initial step time in IOclk ticks
dda->c = ACCELERATION_STEEPNESS << 8;
dda->c_min = (move_duration / target->F) << 8;
dda->n = 1;
dda->ramp_state = RAMP_UP;
#else
dda->c = (move_duration / target->F) << 8;
#endif
#endif
}
if (debug_flags & DEBUG_DDA)
@ -411,6 +421,36 @@ void dda_step(DDA *dda) {
// else we are already at target speed
}
#endif
#ifdef ACCELERATION_RAMPING
// - algorithm courtesy of http://www.embedded.com/columns/technicalinsights/56800129?printable=true
// - for simplicity, taking even/uneven number of steps into account dropped
// - number of steps moved is always accurate, speed might be one step off
switch (dda->ramp_state) {
case RAMP_UP:
case RAMP_MAX:
if (dda->step_no >= dda->ramp_steps) {
// RAMP_UP: time to decelerate before reaching maximum speed
// RAMP_MAX: time to decelerate
dda->ramp_state = RAMP_DOWN;
dda->n = -((int32_t)2) - dda->n;
}
if (dda->ramp_state == RAMP_MAX)
break;
case RAMP_DOWN:
dda->n += 4;
// be careful of signedness!
dda->c = (int32_t)dda->c - ((int32_t)(dda->c * 2) / dda->n);
if (dda->c <= dda->c_min) {
// maximum speed reached
dda->c = dda->c_min;
dda->ramp_state = RAMP_MAX;
dda->ramp_steps = dda->total_steps - dda->step_no;
}
setTimer(dda->c >> 8);
break;
}
dda->step_no++;
#endif
if (did_step) {
// we stepped, reset timeout

21
dda.h
View File

@ -6,6 +6,16 @@
#include "pinout.h"
#include "machine.h"
/*
enums
*/
// wether we accelerate, run at full speed, break down, etc.
typedef enum {
RAMP_UP,
RAMP_MAX,
RAMP_DOWN
} ramp_state_t;
/*
types
*/
@ -66,6 +76,17 @@ typedef struct {
uint32_t end_c;
int32_t n;
#endif
#ifdef ACCELERATION_RAMPING
// start of down-ramp, intitalized with total_steps / 2
uint32_t ramp_steps;
// counts actual steps done
uint32_t step_no;
// 24.8 fixed point timer value, maximum speed
uint32_t c_min;
// tracking variable
int32_t n;
ramp_state_t ramp_state;
#endif
} DDA;
/*

View File

@ -41,6 +41,22 @@
// to reach target speed at the end of the movement.
#define ACCELERATION_REPRAP
// acceleration and deceleration ramping. Each movement starts at
// (almost) no speed, linearly accelerates to target speed and decelerates
// just in time to smoothly stop at the target.
// alternative to ACCELERATION_REPRAP
//#define ACCELERATION_RAMPING
// how fast to accelerate when using ACCELERATION_RAMPING
// smaller values give quicker acceleration
// valid range = 1 to 8,000,000; 500,000 is a good starting point
#define ACCELERATION_STEEPNESS 500000
#ifdef ACCELERATION_REPRAP
#ifdef ACCELERATION_RAMPING
#error Cant use ACCELERATION_REPRAP and ACCELERATION_RAMPING together.
#endif
#endif
// --------------------------------------------------------------------------
// you shouldn't need to edit something below this line