dda: move dda->n out into a new state variable

This required to also introduce dda_init() and re-adjust the
number of accelerating steps a bit.

Goal of this is to make look-ahead possible by just reducing
the number of deceleration steps and acceleration steps of
the next move. dda->c and dda->n no longer go down to their
initial values, then.

Also, quite a number of variables in the dda struct are used only when
the dda is live, so there is no need to store that for each
movement of the queue.
This commit is contained in:
Markus Hitter 2011-05-15 14:56:17 +02:00
parent 2f7619ae26
commit 51be23177a
3 changed files with 60 additions and 18 deletions

40
dda.c
View File

@ -12,6 +12,7 @@
#include "timer.h" #include "timer.h"
#include "serial.h" #include "serial.h"
#include "sermsg.h" #include "sermsg.h"
#include "gcode_parse.h"
#include "dda_queue.h" #include "dda_queue.h"
#include "debug.h" #include "debug.h"
#include "sersendf.h" #include "sersendf.h"
@ -39,6 +40,10 @@ TARGET startpoint __attribute__ ((__section__ (".bss")));
/// \todo make current_position = real_position (from endstops) + offset from G28 and friends /// \todo make current_position = real_position (from endstops) + offset from G28 and friends
TARGET current_position __attribute__ ((__section__ (".bss"))); TARGET current_position __attribute__ ((__section__ (".bss")));
/// \var move_state
/// \brief numbers for tracking the current state of movement
MOVE_STATE move_state __attribute__ ((__section__ (".bss")));
/* /*
utility functions utility functions
*/ */
@ -160,6 +165,17 @@ const uint8_t msbloc (uint32_t v) {
return 0; return 0;
} }
/*! Inititalise DDA movement structures
*/
void dda_init(void) {
// set up default feedrate
current_position.F = startpoint.F = next_target.target.F = SEARCH_FEEDRATE_Z;
#ifdef ACCELERATION_RAMPING
move_state.n = 1;
#endif
}
/*! CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue /*! CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue
\param *dda pointer to a dda_queue entry to overwrite \param *dda pointer to a dda_queue entry to overwrite
\param *target the target position of this move \param *target the target position of this move
@ -350,10 +366,6 @@ void dda_create(DDA *dda, TARGET *target) {
if (dda->rampup_steps > dda->total_steps / 2) if (dda->rampup_steps > dda->total_steps / 2)
dda->rampup_steps = dda->total_steps / 2; dda->rampup_steps = dda->total_steps / 2;
dda->rampdown_steps = dda->total_steps - dda->rampup_steps; dda->rampdown_steps = dda->total_steps - dda->rampup_steps;
if (dda->rampup_steps == 0)
dda->rampup_steps = 1;
dda->n = 1; // TODO: this ends exactly where the next move starts,
// so it should go out of dda->... into some state variable
#else #else
dda->c = (move_duration / target->F) << 8; dda->c = (move_duration / target->F) << 8;
if (dda->c < c_limit) if (dda->c < c_limit)
@ -524,31 +536,31 @@ void dda_step(DDA *dda) {
// debug ramping algorithm // debug ramping algorithm
//if (dda->step_no == 0) { //if (dda->step_no == 0) {
// sersendf_P(PSTR("\r\nc %lu c_min %lu n %ld"), dda->c, dda->c_min, dda->n); // sersendf_P(PSTR("\r\nc %lu c_min %lu n %ld"), dda->c, dda->c_min, move_state.n);
//} //}
recalc_speed = 0; recalc_speed = 0;
if (dda->step_no <= dda->rampup_steps) { if (dda->step_no < dda->rampup_steps) {
if (dda->n < 0) // wrong ramp direction if (move_state.n < 0) // wrong ramp direction
dda->n = -((int32_t)2) - dda->n; move_state.n = -((int32_t)2) - move_state.n;
recalc_speed = 1; recalc_speed = 1;
} }
else if (dda->step_no >= dda->rampdown_steps) { else if (dda->step_no > dda->rampdown_steps) {
if (dda->n > 0) // wrong ramp direction if (move_state.n > 0) // wrong ramp direction
dda->n = -((int32_t)2) - dda->n; move_state.n = -((int32_t)2) - move_state.n;
recalc_speed = 1; recalc_speed = 1;
} }
if (recalc_speed) { if (recalc_speed) {
dda->n += 4; move_state.n += 4;
// be careful of signedness! // be careful of signedness!
dda->c = (int32_t)dda->c - ((int32_t)(dda->c * 2) / dda->n); dda->c = (int32_t)dda->c - ((int32_t)(dda->c * 2) / move_state.n);
} }
dda->step_no++; dda->step_no++;
// debug ramping algorithm // debug ramping algorithm
// for very low speeds like 10 mm/min, only // for very low speeds like 10 mm/min, only
//if (dda->step_no % 10 /* 10, 100, ...*/ == 0) //if (dda->step_no % 10 /* 10, 100, ...*/ == 0)
// sersendf_P(PSTR("\r\nc %lu c_min %lu n %ld"), dda->c, dda->c_min, dda->n); // sersendf_P(PSTR("\r\nc %lu c_min %lu n %ld"), dda->c, dda->c_min, move_state.n);
#endif #endif
// TODO: did_step is obsolete ... // TODO: did_step is obsolete ...

34
dda.h
View File

@ -34,6 +34,35 @@ typedef struct {
uint32_t F; uint32_t F;
} TARGET; } TARGET;
/**
\struct MOVE_STATE
\brief this struct is made for tracking the current state of the movement
Parts of this struct are initialised only once per reboot, so make sure dda_step() leaves them with a value compatible to begin a new movement at the end of the movement. Other parts are filled in by dda_start().
*/
typedef struct {
// // bresenham counters
// int32_t x_counter; ///< counter for total_steps vs this axis
// int32_t y_counter; ///< counter for total_steps vs this axis
// int32_t z_counter; ///< counter for total_steps vs this axis
// int32_t e_counter; ///< counter for total_steps vs this axis
// // step counters
// uint32_t x_steps; ///< number of steps on X axis
// uint32_t y_steps; ///< number of steps on Y axis
// uint32_t z_steps; ///< number of steps on Z axis
// uint32_t e_steps; ///< number of steps on E axis
#ifdef ACCELERATION_RAMPING
// /// time until next step
// uint32_t c;
// /// counts actual steps done
// uint32_t step_no;
/// tracking variable
int32_t n;
#endif
} MOVE_STATE;
/** /**
\struct DDA \struct DDA
\brief this is a digital differential analyser data struct \brief this is a digital differential analyser data struct
@ -102,8 +131,6 @@ typedef struct {
uint32_t step_no; uint32_t step_no;
/// 24.8 fixed point timer value, maximum speed /// 24.8 fixed point timer value, maximum speed
uint32_t c_min; uint32_t c_min;
/// tracking variable
int32_t n;
#endif #endif
} DDA; } DDA;
@ -131,6 +158,9 @@ uint32_t approx_distance_3( uint32_t dx, uint32_t dy, uint32_t dz ) __attribute_
// const because return value is always the same given the same v // const because return value is always the same given the same v
const uint8_t msbloc (uint32_t v) __attribute__ ((const)); const uint8_t msbloc (uint32_t v) __attribute__ ((const));
// initialize dda structures
void dda_init(void);
// create a DDA // create a DDA
void dda_create(DDA *dda, TARGET *target); void dda_create(DDA *dda, TARGET *target);

View File

@ -225,8 +225,8 @@ void init(void) {
// read PID settings from EEPROM // read PID settings from EEPROM
heater_init(); heater_init();
// set up default feedrate // set up dda
current_position.F = startpoint.F = next_target.target.F = SEARCH_FEEDRATE_Z; dda_init();
// start up analog read interrupt loop, // start up analog read interrupt loop,
// if any of the temp sensors in your config.h use analog interface // if any of the temp sensors in your config.h use analog interface