Checkpoint - generalizing planner buffer handling

This commit is contained in:
Alden Hart
2016-12-05 12:47:26 -05:00
parent ed43317f9f
commit bf3c540f9e
7 changed files with 118 additions and 39 deletions
Executable → Regular
+1
View File
@@ -1,5 +1,6 @@
/*
* hardware.h - system hardware configuration
* for: /board/g2v9
* THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version
*
* This file is part of the g2core project
+11
View File
@@ -537,6 +537,17 @@ stat_t mp_exec_aline(mpBuf_t *bf)
return (status);
}
/*
* mp_plan_feedhold_move() - plan Z lift moves for feedhold
*/
stat_t mp_plan_feedhold_move()
{
return (STAT_OK);
}
/*
* mp_exit_hold_state() - end a feedhold
*
+17 -16
View File
@@ -129,16 +129,15 @@ bool mp_runtime_is_idle() { return (!st_runtime_isbusy()); }
* Controlling jerk smooths transitions between moves and allows for faster feeds while
* controlling machine oscillations and other undesirable side-effects.
*
* Note All math is done in absolute coordinates using single precision floating point (float).
* Note: All math is done in absolute coordinates using single precision floating point (float).
*
* Note: Returning a status that is not STAT_OK means the endpoint is NOT advanced. So lines
* that are too short to move will accumulate and get executed once the accumulated error
* exceeds the minimums.
*/
stat_t mp_aline(GCodeState_t* gm_in)
stat_t mp_aline(GCodeState_t* gm_in)
{
mpBuf_t* bf; // current move pointer
float target_rotated[AXES] = {0, 0, 0, 0, 0, 0};
float axis_square[AXES] = {0, 0, 0, 0, 0, 0};
float axis_length[AXES];
@@ -191,33 +190,35 @@ stat_t mp_aline(GCodeState_t* gm_in)
// exit if the move has zero movement. At all.
if (fp_ZERO(length)) {
sr_request_status_report(SR_REQUEST_TIMED_FULL); // Was SR_REQUEST_IMMEDIATE_FULL
sr_request_status_report(SR_REQUEST_TIMED_FULL); // Was SR_REQUEST_IMMEDIATE_FULL
return (STAT_MINIMUM_LENGTH_MOVE);
}
// get a cleared buffer and copy in the Gcode model state
if ((bf = mp_get_write_buffer()) == NULL) { // never supposed to fail
mpBuf_t* bf = mp_get_write_buffer();
if (bf == NULL) { // never supposed to fail
// if ((bf = mp_get_write_buffer()) == NULL) { // never supposed to fail
return (cm_panic(STAT_FAILED_GET_PLANNER_BUFFER, "aline()"));
}
memcpy(&bf->gm, gm_in, sizeof(GCodeState_t));
// Since bf->gm.target is being used all over the place, we'll make it the rotated target
copy_vector(bf->gm.target, target_rotated); // copy the rotated taget in place
copy_vector(bf->gm.target, target_rotated); // copy the rotated taget in place
// setup the buffer
bf->bf_func = mp_exec_aline; // register the callback to the exec function
bf->length = length; // record the length
for (uint8_t axis = 0; axis < AXES; axis++) { // compute the unit vector and set flags
if ((bf->axis_flags[axis] = flags[axis])) { // yes, this is supposed to be = and not ==
bf->unit[axis] = axis_length[axis] / length; // nb: bf-> unit was cleared by mp_get_write_buffer()
bf->bf_func = mp_exec_aline; // register the callback to the exec function
bf->length = length; // record the length
for (uint8_t axis = 0; axis < AXES; axis++) { // compute the unit vector and set flags
if ((bf->axis_flags[axis] = flags[axis])) { // yes, this is supposed to be = and not ==
bf->unit[axis] = axis_length[axis] / length;// nb: bf-> unit was cleared by mp_get_write_buffer()
}
}
_calculate_jerk(bf); // compute bf->jerk values
_calculate_vmaxes(bf, axis_length, axis_square); // compute cruise_vmax and absolute_vmax
_set_bf_diagnostics(bf); //+++++DIAGNOSTIC
_calculate_jerk(bf); // compute bf->jerk values
_calculate_vmaxes(bf, axis_length, axis_square); // compute cruise_vmax and absolute_vmax
_set_bf_diagnostics(bf); //+++++DIAGNOSTIC
// Note: these next lines must remain in exact order. Position must update before committing the buffer.
copy_vector(mp.position, bf->gm.target); // set the planner position
mp_commit_write_buffer(BLOCK_TYPE_ALINE); // commit current block (must follow the position update)
copy_vector(mp.position, bf->gm.target); // set the planner position
mp_commit_write_buffer(BLOCK_TYPE_ALINE); // commit current block (must follow the position update)
return (STAT_OK);
}
Executable → Regular
+60 -8
View File
@@ -65,9 +65,10 @@
#include "xio.h" //+++++ DIAGNOSTIC - only needed if xio_writeline() direct prints are used
// Allocate planner structures
mpBufferPool_t mb; // buffer pool management
mpMotionPlannerSingleton_t mp; // context for block planning
mpMotionRuntimeSingleton_t mr; // context for block runtime
mpBufferPool_t mb; // buffer pool management
mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for pool #1 buffers
mpMotionPlannerSingleton_t mp; // context for block planning
mpMotionRuntimeSingleton_t mr; // context for block runtime
#define JSON_COMMAND_BUFFER_SIZE 3
@@ -700,15 +701,68 @@ static inline void _clear_buffer(mpBuf_t *bf)
bf->clear();
}
void mp_init_buffers(void)
void _init_buffers(mpBuf_t *base, uint8_t size)
{
mpBuf_t *pv, *nx;
uint8_t i, nx_i;
memset(&mb, 0, sizeof(mb)); // clear all values, pointers and status
// memset(base, 0, sizeof(mpBuf_t * size)); // clear all buffers in pool
mb.bf = base; // link the buffer pool first
mb.w = mb.bf; // init all buffer pointers
mb.r = mb.bf;
mb.queue_size = size-1;
mb.buffers_available = size;
pv = &mb.bf[size-1];
for (i=0; i < size-1; i++) {
mb.bf[i].buffer_number = i; //+++++ number it for diagnostics only (otherwise not used)
nx_i = ((i<size-1) ? (i+1) : 0); // buffer increment & wrap
nx = &mb.bf[nx_i];
mb.bf[i].nx = nx; // setup circular list pointers
mb.bf[i].pv = pv;
pv = &mb.bf[i];
}
}
void mp_init_buffers(void)
{
// mpBuf_t *pv, *nx;
// uint8_t i, nx_i;
// memset(&mb_pool0, 0, sizeof(mb_pool0)); // clear all buffers in pool
memset(&mb, 0, sizeof(mb)); // clear values, pointers and status
mb.magic_start = MAGICNUM;
mb.magic_end = MAGICNUM;
_init_buffers(mb_pool0, PLANNER_BUFFER_POOL_SIZE);
/*
mb.bf = mb_pool0; // link the buffer pool first
mb.w = mb.bf; // init all buffer pointers
mb.r = mb.bf;
mb.buffers_total = PLANNER_BUFFER_POOL_SIZE-1;
pv = &mb.bf[PLANNER_BUFFER_POOL_SIZE-1];
for (i=0; i < mb.buffers_total; i++) {
mb.bf[i].buffer_number = i; //+++++ number it for diagnostics only (otherwise not used)
nx_i = ((i<mb.buffers_total) ? (i+1) : 0); // buffer increment & wrap
nx = &mb.bf[nx_i];
mb.bf[i].nx = nx; // setup ring pointers
mb.bf[i].pv = pv;
pv = &mb.bf[i];
}
mb.buffers_available = PLANNER_BUFFER_POOL_SIZE;
*/
// Now handle the two "stub buffers" in the runtime structure.
mr.bf[0].nx = &mr.bf[1];
mr.bf[1].nx = &mr.bf[0];
mr.r = &mr.bf[0];
mr.p = &mr.bf[1];
}
/*
mb.w = &mb.bf[0]; // init all buffer pointers
mb.r = &mb.bf[0];
pv = &mb.bf[PLANNER_BUFFER_POOL_SIZE-1];
@@ -724,15 +778,13 @@ void mp_init_buffers(void)
}
mb.buffers_available = PLANNER_BUFFER_POOL_SIZE;
// mb.entry_changed = false;
// Now handle the two "stub buffers" in the runtime structure.
mr.bf[0].nx = &mr.bf[1];
mr.bf[1].nx = &mr.bf[0];
mr.r = &mr.bf[0];
mr.p = &mr.bf[1];
}
*/
/*
* These GET functions are defined here but we use the macros in planner.h instead
*
Executable → Regular
+14 -1
View File
@@ -125,6 +125,7 @@ typedef enum {
#define PLANNER_BUFFER_POOL_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255
#define PLANNER_BUFFER_HEADROOM ((uint8_t)4) // Buffers to reserve in planner before processing new input line
#define SECONDARY_BUFFER_POOL_SIZE ((uint8_t)4) // Secondary planner queue for feedhold operations
#define JERK_MULTIPLIER ((float)1000000) // DO NOT CHANGE - must always be 1 million
#define JUNCTION_INTEGRATION_MIN (0.05) // minimum allowable setting
@@ -241,7 +242,7 @@ typedef struct mpBuffer : mpBuffer_to_clear { // See Planning Velocity Notes for
struct mpBuffer *nx; // static pointer to next buffer
uint8_t buffer_number; //+++++ DIAGNOSTIC for easier debugging
} mpBuf_t;
/*
typedef struct mpBufferPool { // ring buffer for sub-moves
magic_t magic_start; // magic number to test memory integrity
@@ -249,7 +250,19 @@ typedef struct mpBufferPool { // ring buffer for sub-moves
mpBuf_t *w; // write buffer pointer
uint8_t buffers_available; // running count of available buffers
mpBuf_t bf[PLANNER_BUFFER_POOL_SIZE];// buffer storage
magic_t magic_end;
} mpBufferPool_t;
*/
typedef struct mpBufferPool { // one or more planner buffer queues
magic_t magic_start; // magic number to test memory integrity
mpBuf_t *r; // run buffer pointer
mpBuf_t *w; // write buffer pointer
uint8_t queue_size; // total number of buffers, zero-based (e.g. 47 not 48)
uint8_t buffers_available; // running count of available buffers
mpBuf_t *bf; // pointer to buffer storage array
magic_t magic_end;
} mpBufferPool_t;
+14 -13
View File
@@ -430,28 +430,29 @@ static void _load_move()
// Be aware that dda_ticks_downcount must equal zero for the loader to run.
// So the initial load must also have this set to zero as part of initialization
if (st_runtime_isbusy()) {
return; // exit if the runtime is busy
return; // exit if the runtime is busy
}
if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) { // if there are no moves to load...
// ...start motor power timeouts
// for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) {
// Motors[motor]->motionStopped();
// }
// loop unrolled version
// If there are no moves to load start motor power timeouts
if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) {
// for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) {
// Motors[motor]->motionStopped();
// }
// loop unrolled version
motor_1.motionStopped(); // ...start motor power timeouts
motor_2.motionStopped(); // ...start motor power timeouts
motor_2.motionStopped();
#if (MOTORS > 2)
motor_3.motionStopped(); // ...start motor power timeouts
motor_3.motionStopped();
#endif
#if (MOTORS > 3)
motor_4.motionStopped(); // ...start motor power timeouts
motor_4.motionStopped();
#endif
#if (MOTORS > 4)
motor_5.motionStopped(); // ...start motor power timeouts
motor_5.motionStopped();
#endif
#if (MOTORS > 5)
motor_6.motionStopped(); // ...start motor power timeouts
motor_6.motionStopped();
#endif
return;
}
+1 -1
View File
@@ -515,7 +515,7 @@ struct Stepper {
}
}
};
virtual void periodicCheck(bool have_actually_stopped) // can be overridden
{
if (have_actually_stopped && _power_state == MOTOR_RUNNING) {