mirror of
https://github.com/synthetos/g2.git
synced 2026-09-22 03:08:42 +08:00
Checkpoint added Primary and Alternate planner queue section from the buffer primitives
This commit is contained in:
Executable → Regular
+4
-4
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user