Checkpoint added Primary and Alternate planner queue section from the buffer primitives

This commit is contained in:
Alden Hart
2016-12-05 15:47:41 -05:00
parent 0d0fdd9ddb
commit 470923f0f7
9 changed files with 169 additions and 71 deletions
Executable → Regular
+4 -4
View File
@@ -1248,7 +1248,7 @@ stat_t cm_straight_traverse(const float target[], const bool flags[])
cm_cycle_start(); // required for homing & other cycles
stat_t status = mp_aline(&cm.gm); // send the move to the planner
cm_finalize_move();
if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer()) {
if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(ACTIVE_Q)) {
cm_cycle_end();
return (STAT_OK);
}
@@ -1277,7 +1277,7 @@ stat_t _goto_stored_position(float target2[], const float target[], const bool f
target2[i] -= target[i];
}
}
while (mp_planner_is_full()); // Make sure you have available buffers
while (mp_planner_is_full(ACTIVE_Q)); // Make sure you have available buffers
bool flags2[] = { 1,1,1,1,1,1 };
return (cm_straight_traverse(target2, flags2)); // Go to programmed endpoint
@@ -1395,7 +1395,7 @@ stat_t cm_straight_feed(const float target[], const bool flags[])
cm_finalize_move(); // <-- ONLY safe because we don't care about status...
if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer()) {
if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(ACTIVE_Q)) {
cm_cycle_end();
return (STAT_OK);
}
@@ -1720,7 +1720,7 @@ bool cm_has_hold()
void cm_start_hold()
{
if (mp_has_runnable_buffer()) { // meaning there's something running
if (mp_has_runnable_buffer(ACTIVE_Q)) { // meaning there's something running
cm_spindle_optional_pause(spindle.pause_on_hold); // pause if this option is selected
cm_coolant_optional_pause(coolant.pause_on_hold); // pause if this option is selected
cm_set_motion_state(MOTION_HOLD);
Executable → Regular
+2 -2
View File
@@ -201,7 +201,7 @@ static stat_t _dispatch_command()
{
if (cs.controller_state != CONTROLLER_PAUSED) {
devflags_t flags = DEV_IS_BOTH;
if ((!mp_planner_is_full()) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) {
if ((!mp_planner_is_full(ACTIVE_Q)) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) {
_dispatch_kernel();
}
}
@@ -350,7 +350,7 @@ static stat_t _sync_to_tx_buffer()
static stat_t _sync_to_planner()
{
if (mp_planner_is_full()) { // allow up to N planner buffers for this line
if (mp_planner_is_full(ACTIVE_Q)) { // allow up to N planner buffers for this line
return (STAT_EAGAIN);
}
return (STAT_OK);
Executable → Regular
+2 -2
View File
@@ -130,7 +130,7 @@ stat_t cm_jogging_cycle_callback(void) {
return (STAT_EAGAIN); // sync to planner move ends
}
// if (jog.func == _jogging_axis_ramp_jog && mp_get_buffers_available() < PLANNER_BUFFER_HEADROOM) {
if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full()) {
if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full(ACTIVE_Q)) {
return (STAT_EAGAIN); // prevent flooding the queue with jog moves
}
return (jog.func(jog.axis)); // execute the current jogging move
@@ -142,7 +142,7 @@ static stat_t _set_jogging_func(stat_t (*func)(int8_t axis)) {
}
static stat_t _jogging_axis_start(int8_t axis) {
// cm_end_hold(); // ends hold if one is in effect
// cm_end_hold(); // ends hold if one is in effect
return (_set_jogging_func(_jogging_axis_ramp_jog));
}
+1 -1
View File
@@ -78,7 +78,7 @@ stat_t cm_arc_callback()
if (arc.run_state == BLOCK_INACTIVE) {
return (STAT_NOOP);
}
if (mp_planner_is_full()) {
if (mp_planner_is_full(ACTIVE_Q)) {
return (STAT_EAGAIN);
}
arc.theta += arc.segment_theta;
+5 -4
View File
@@ -419,8 +419,8 @@ stat_t mp_exec_aline(mpBuf_t *bf)
// Case (5) - decelerated to zero
// Update the run buffer then force a replan of the whole planner queue
if (cm.hold_state == FEEDHOLD_DECEL_END) {
mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move
bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer
mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move
bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer
bf->length = get_axis_vector_length(mr.target, mr.position);// reset length
//bf->entry_vmax = 0; // set bp+0 as hold point
@@ -431,7 +431,8 @@ stat_t mp_exec_aline(mpBuf_t *bf)
mp_free_run_buffer();
}
mp_replan_queue(mb.r); // make it replan all the blocks
mp_replan_queue(mp_get_r(ACTIVE_Q)); // make it replan all the blocks
// mp_replan_queue(mb.r); // make it replan all the blocks
return (STAT_OK);
}
@@ -560,7 +561,7 @@ stat_t mp_plan_feedhold_move()
void mp_exit_hold_state()
{
cm.hold_state = FEEDHOLD_OFF;
if (mp_has_runnable_buffer()) {
if (mp_has_runnable_buffer(ACTIVE_Q)) {
cm_set_motion_state(MOTION_RUN);
sr_request_status_report(SR_REQUEST_IMMEDIATE);
} else {
+3 -1
View File
@@ -112,7 +112,9 @@ bool mp_get_runtime_busy()
if (cm.cycle_state == CYCLE_OFF) {
return (false);
}
if ((st_runtime_isbusy() == true) || (mr.block_state == BLOCK_ACTIVE) || (mb.r->buffer_state > MP_BUFFER_EMPTY)) {
if ((st_runtime_isbusy() == true) ||
(mr.block_state == BLOCK_ACTIVE) ||
(mp_get_r(ACTIVE_Q)->buffer_state > MP_BUFFER_EMPTY)) {
return (true);
}
return (false);
+130 -45
View File
@@ -65,8 +65,9 @@
#include "xio.h" //+++++ DIAGNOSTIC - only needed if xio_writeline() direct prints are used
// Allocate planner structures
mpBufferPool_t mb; // buffer pool management
mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for pool #1 buffers
mpBufferQueue_t mb; // buffer pool management
mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers
mpBuf_t mb_pool1[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers
mpMotionPlannerSingleton_t mp; // context for block planning
mpMotionRuntimeSingleton_t mr; // context for block runtime
@@ -168,11 +169,13 @@ void planner_init_assertions()
stat_t planner_test_assertions()
{
/* +++++ Fix this
if ((BAD_MAGIC(mb.magic_start)) || (BAD_MAGIC(mb.magic_end)) ||
(BAD_MAGIC(mp.magic_start)) || (BAD_MAGIC(mp.magic_end)) ||
(BAD_MAGIC(mr.magic_start)) || (BAD_MAGIC(mr.magic_end))) {
return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()"));
}
*/
return (STAT_OK);
}
@@ -433,22 +436,27 @@ stat_t mp_exec_out_of_band_dwell(void)
* mp_has_runnable_buffer() - true if next buffer is runnable, indicating motion has not stopped.
* mp_is_it_phat_city_time() - test if there is time for non-essential processes
*/
uint8_t mp_get_planner_buffers()
uint8_t mp_get_planner_buffers(int8_t q) // which queue are you interested in?
{
return (mb.buffers_available);
if (q == ACTIVE_Q) { q = mb.active_q; };
return (mb.q[q].buffers_available);
}
bool mp_planner_is_full()
bool mp_planner_is_full(int8_t q) // which queue are you interested in?
{
// We also need to ensure we have room for another JSON command
return ((mb.buffers_available < PLANNER_BUFFER_HEADROOM) || (jc.available == 0));
if (q == ACTIVE_Q) { q = mb.active_q; };
return ((mb.q[q].buffers_available < PLANNER_BUFFER_HEADROOM)
|| (jc.available == 0)); // We also need to ensure we have room for another JSON command
}
bool mp_has_runnable_buffer()
bool mp_has_runnable_buffer(int8_t q) // which queue are you interested in?)
{
return (mb.r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true
if (q == ACTIVE_Q) { q = mb.active_q; };
return (mb.q[q].r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true
}
bool mp_is_phat_city_time()
{
if(cm.hold_state == FEEDHOLD_HOLD) {
@@ -494,7 +502,8 @@ bool mp_is_phat_city_time()
stat_t mp_planner_callback()
{
// Test if the planner has transitioned to an IDLE state
if ((mb.buffers_available == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state
//+++ if ((mb.buffers_available == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state
if ((mp_get_planner_buffers(ACTIVE_Q) == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state
(cm.motion_state == MOTION_STOP) &&
(cm.hold_state == FEEDHOLD_OFF)) {
mp.planner_state = PLANNER_IDLE;
@@ -512,11 +521,12 @@ stat_t mp_planner_callback()
// Process a planner request or timeout
if (mp.planner_state == PLANNER_IDLE) {
mp.p = mb.r; // initialize planner pointer to run buffer
//++++ mp.p = mb.r; // initialize planner pointer to run buffer
mp.p = mp_get_r(ACTIVE_Q); // initialize planner pointer to run buffer
mp.planner_state = PLANNER_STARTUP;
}
if (mp.planner_state == PLANNER_STARTUP) {
if (!mp_planner_is_full() && !_timed_out) {
if (!mp_planner_is_full(ACTIVE_Q) && !_timed_out) {
return (STAT_OK); // remain in STARTUP
}
mp.planner_state = PLANNER_PRIMING;
@@ -534,15 +544,13 @@ stat_t mp_planner_callback()
void mp_replan_queue(mpBuf_t *bf)
{
do {
if (bf->buffer_state >= MP_BUFFER_PLANNED) {
// revert from PLANNED state
if (bf->buffer_state >= MP_BUFFER_PLANNED) { // revert from PLANNED state
bf->buffer_state = MP_BUFFER_PREPPED;
} else {
// If it's not "planned" then it's either PREPPED or earlier.
// We don't need to adjust it.
break;
} else { // If it's not "planned" then it's either PREPPED or earlier.
break; // We don't need to adjust it.
}
} while ((bf = mp_get_next_buffer(bf)) != mb.r);
} while ((bf = mp_get_next_buffer(bf)) != mp_get_r(ACTIVE_Q));
//+++ } while ((bf = mp_get_next_buffer(bf)) != mb.r);
mp.request_planning = true;
}
@@ -599,14 +607,16 @@ void mp_end_feed_override(const float ramp_time)
void mp_planner_time_accounting()
{
mpBuf_t *bf = mb.r; // start with run buffer
//+++ mpBuf_t *bf = mb.r; // start with run buffer
mpBuf_t *bf = mp_get_r(ACTIVE_Q); // start with run buffer
// check the run buffer to see if anything is running. Might not be
if (bf->buffer_state != MP_BUFFER_RUNNING) { // this is not an error condition
return;
}
mp.plannable_time = 0; //UPDATE_BF_MS(bf); //+++++
while ((bf = bf->nx) != mb.r) {
//+++ while ((bf = bf->nx) != mb.r) {
while ((bf = bf->nx) != mp_get_r(ACTIVE_Q)) {
if (bf->buffer_state == MP_BUFFER_EMPTY || bf->plannable == true) {
break;
}
@@ -701,53 +711,71 @@ static inline void _clear_buffer(mpBuf_t *bf)
bf->clear();
}
void _init_buffer_pool(mpBuf_t *base, uint8_t size)
void _init_planner_queue(uint8_t q, mpBuf_t *pool, uint8_t size)
{
mpBuf_t *pv, *nx;
uint8_t i, nx_i;
memset(&mb.q[q], 0, sizeof(mpQueue_t)); // clear values, pointers and status
mb.q[q].magic_start = MAGICNUM;
mb.q[q].magic_end = MAGICNUM;
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;
memset(pool, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool
mb.q[q].bf = pool; // link the buffer pool first
mb.q[q].w = pool; // init all buffer pointers
mb.q[q].r = pool;
mb.q[q].queue_size = size-1;
mb.q[q].buffers_available = size;
pv = &mb.bf[size-1];
pv = &mb.q[q].bf[size-1];
for (i=0; i < size-1; i++) {
mb.bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used)
mb.q[q].bf[i].buffer_number = i; // number is 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];
nx = &mb.q[q].bf[nx_i];
mb.q[q].bf[i].nx = nx; // setup circular list pointers
mb.q[q].bf[i].pv = pv;
pv = &mb.q[q].bf[i];
}
}
void mp_init_buffers(void)
{
memset(&mb, 0, sizeof(mb)); // clear values, pointers and status
mb.magic_start = MAGICNUM;
mb.magic_end = MAGICNUM;
_init_planner_queue(0, mb_pool0, PLANNER_BUFFER_POOL_SIZE);
// _init_planner_queue(1, mb_pool1, SECONDARY_BUFFER_POOL_SIZE);
_init_buffer_pool(mb_pool0, PLANNER_BUFFER_POOL_SIZE);
// Now handle the two "stub buffers" in the runtime structure.
// Now handle the two "stub blocks" 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
*
mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf) { return (bf->pv); }
mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf) { return (bf->nx); }
*/
*/
mpBuf_t * mp_get_w(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].w : mb.q[q].w); }
mpBuf_t * mp_get_r(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].r : mb.q[q].r); }
mpBuf_t * mp_get_write_buffer() // get & clear a buffer
{
mpBuf_t *w = mb.q[mb.active_q].w;
mpQueue_t *q = &mb.q[mb.active_q];
if (q->w->buffer_state == MP_BUFFER_EMPTY) {
_clear_buffer(w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer
w->buffer_state = MP_BUFFER_INITIALIZING;
mb.q[mb.active_q].buffers_available--;
return (mp_get_w(ACTIVE_Q));
}
// The no buffer condition always causes a panic - invoked by the caller
rpt_exception(STAT_FAILED_TO_GET_PLANNER_BUFFER, "mp_get_write_buffer()");
return (NULL);
/*
if (mb.w->buffer_state == MP_BUFFER_EMPTY) {
_clear_buffer(mb.w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer
mb.w->buffer_state = MP_BUFFER_INITIALIZING;
@@ -758,14 +786,23 @@ mpBuf_t * mp_get_write_buffer() // get & clear a buffer
// The no buffer condition always causes a panic - invoked by the caller
rpt_exception(STAT_FAILED_TO_GET_PLANNER_BUFFER, "mp_get_write_buffer()");
return (NULL);
*/
}
void mp_unget_write_buffer() // mark buffer as empty and adjust free buffer count
{
mpBuf_t *w = mb.q[mb.active_q].w;
if (w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer
w->buffer_state = MP_BUFFER_EMPTY;
mb.q[mb.active_q].buffers_available++;
}
/*
if (mb.w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer
mb.w->buffer_state = MP_BUFFER_EMPTY;
mb.buffers_available++;
}
*/
}
/*** WARNING ***
@@ -775,6 +812,28 @@ void mp_unget_write_buffer() // mark buffer as empty and adjust free buff
void mp_commit_write_buffer(const blockType block_type)
{
mpBuf_t *w = mb.q[mb.active_q].w;
w->block_type = block_type;
w->block_state = BLOCK_INITIAL_ACTION;
if (block_type == BLOCK_TYPE_ALINE) {
if (cm.motion_state == MOTION_STOP) {
cm_set_motion_state(MOTION_PLANNING);
}
} else {
if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) {
// NB: BEWARE! the exec may result in the planner buffer being
// processed IMMEDIATELY and then freed - invalidating the contents
st_request_plan_move(); // request an exec if the runtime is not busy
}
}
w->plannable = true; // enable block for planning
mp.request_planning = true;
mb.q[mb.active_q].w = w->nx; // advance write buffer pointer
mp.block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer
qr_request_queue_report(+1); // request QR and add to "added buffers" count
/*
mb.w->block_type = block_type;
mb.w->block_state = BLOCK_INITIAL_ACTION;
@@ -782,7 +841,7 @@ void mp_commit_write_buffer(const blockType block_type)
if (cm.motion_state == MOTION_STOP) {
cm_set_motion_state(MOTION_PLANNING);
}
} else {
} else {
if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) {
// NB: BEWARE! the exec may result in the planner buffer being
// processed IMMEDIATELY and then freed - invalidating the contents
@@ -794,11 +853,25 @@ void mp_commit_write_buffer(const blockType block_type)
mb.w = mb.w->nx; // advance write buffer pointer
mp.block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer
qr_request_queue_report(+1); // request QR and add to "added buffers" count
*/
}
// Note: mp_get_run_buffer() is only called by mp_exec_move(), which is inside an interrupt
mpBuf_t * mp_get_run_buffer()
{
mpBuf_t *r = mb.q[mb.active_q].r;
// EMPTY is the one case where nothing is returned. This is not an error
if (r->buffer_state == MP_BUFFER_EMPTY) {
return (NULL);
}
// Otherwise return the buffer. Let mp_exec_move() manage the state machine to sort out:
// (1) is the the first time the run buffer has been retrieved?
// (2) is the buffer in error - i.e. not yet ready for running?
return (r);
}
/*
// EMPTY is the one case where nothing is returned. This is not an error
if (mb.r->buffer_state == MP_BUFFER_EMPTY) {
return (NULL);
@@ -808,12 +881,23 @@ mpBuf_t * mp_get_run_buffer()
// (2) is the buffer in error - i.e. not yet ready for running?
return (mb.r);
}
*/
// Note: mp_free_run_buffer() is only called from mp_exec_XXX, which are within an interrupt
bool mp_free_run_buffer() // EMPTY current run buffer & advance to the next
{
_audit_buffers(); // diagnostic audit for buffer chain integrity (only runs in DEBUG mode)
mpBuf_t *r = mb.q[mb.active_q].r;
// _audit_buffers(); // ++++diagnostic audit for buffer chain integrity (only runs in DEBUG mode)
mb.q[mb.active_q].r = r->nx; // advance to next run buffer
_clear_buffer(r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY)
mb.q[mb.active_q].buffers_available++;
qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count
return (mb.q[mb.active_q].w == mb.q[mb.active_q].r); // return true if the queue emptied
/*
return (mb.w == mb.r); // return true if the queue emptied
mpBuf_t *r = mb.r;
mb.r = mb.r->nx; // advance to next run buffer
_clear_buffer(r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY)
@@ -821,6 +905,7 @@ bool mp_free_run_buffer() // EMPTY current run buffer & advance to the
mb.buffers_available++;
qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count
return (mb.w == mb.r); // return true if the queue emptied
*/
}
/* UNUSED FUNCTIONS - left in for completeness and for reference
+20 -10
View File
@@ -124,8 +124,8 @@ typedef enum {
/*** Most of these factors are the result of a lot of tweaking. Change with caution.***/
#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 PLANNER_BUFFER_HEADROOM ((uint8_t)4) // Buffers to reserve in planner before processing new input line
#define JERK_MULTIPLIER ((float)1000000) // DO NOT CHANGE - must always be 1 million
#define JUNCTION_INTEGRATION_MIN (0.05) // minimum allowable setting
@@ -172,6 +172,11 @@ typedef enum {
//#define UPDATE_BF_DIAGNOSTICS(bf) { bf->block_time_ms = bf->block_time*60000; bf->plannable_time_ms = bf->plannable_time*60000; }
#define UPDATE_MP_DIAGNOSTICS { mp.plannable_time_ms = mp.plannable_time*60000; }
// Define which queue you are interested in for input args
#define PRIMARY_Q 0
#define SECONDARY_Q 1
#define ACTIVE_Q -1
/*
* Planner structures
*/
@@ -243,17 +248,20 @@ typedef struct mpBuffer : mpBuffer_to_clear { // See Planning Velocity Notes for
uint8_t buffer_number; //+++++ DIAGNOSTIC for easier debugging
} mpBuf_t;
typedef struct mpBufferPool { // one or more planner buffer queues
typedef struct mpQueue { // a planner buffer queue
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
uint8_t buffers_available; // running count of available buffers in queue
mpBuf_t *bf; // pointer to buffer storage array
magic_t magic_end;
} mpBufferPool_t;
} mpQueue_t;
typedef struct mpBufferQueue { // one or more planner buffer queues
uint8_t active_q; // index of currently active queue
mpQueue_t q[2]; // number of queues
} mpBufferQueue_t;
typedef struct mpMotionPlannerSingleton { // common variables for planning (move master)
magic_t magic_start; // magic number to test memory integrity
@@ -350,7 +358,7 @@ typedef struct mpMotionRuntimeSingleton { // persistent runtime variables
} mpMotionRuntimeSingleton_t;
// Reference global scope structures
extern mpBufferPool_t mb; // buffer pool management
extern mpBufferQueue_t mb; // planner buffer queue management
extern mpMotionPlannerSingleton_t mp; // context for block planning
extern mpMotionRuntimeSingleton_t mr; // context for block runtime
@@ -383,9 +391,9 @@ void mp_request_out_of_band_dwell(float seconds);
stat_t mp_exec_out_of_band_dwell(void);
// planner functions and helpers
uint8_t mp_get_planner_buffers(void);
bool mp_planner_is_full(void);
bool mp_has_runnable_buffer(void);
uint8_t mp_get_planner_buffers(int8_t q);
bool mp_planner_is_full(int8_t q);
bool mp_has_runnable_buffer(int8_t q);
bool mp_is_phat_city_time(void);
stat_t mp_planner_callback();
@@ -396,6 +404,8 @@ void mp_planner_time_accounting(void);
// planner buffer primitives
void mp_init_buffers(void);
mpBuf_t * mp_get_w(int8_t q);
mpBuf_t * mp_get_r(int8_t q);
//mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf); // Use the following macro instead
//mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf); // Use the following macro instead
+2 -2
View File
@@ -491,7 +491,7 @@ void qr_init_queue_report()
void qr_request_queue_report(int8_t buffers)
{
// get buffer depth and added/removed count
qr.buffers_available = mp_get_planner_buffers();
qr.buffers_available = mp_get_planner_buffers(ACTIVE_Q);
if (buffers > 0) {
qr.buffers_added += buffers;
} else {
@@ -574,7 +574,7 @@ stat_t qr_queue_report_callback() // called by controller dispatcher
*/
stat_t qr_get(nvObj_t *nv)
{
nv->value = (float)mp_get_planner_buffers(); // ensure that manually requested QR count is always up to date
nv->value = (float)mp_get_planner_buffers(ACTIVE_Q); // ensure that manually requested QR count is always up to date
nv->valuetype = TYPE_INT;
return (STAT_OK);
}