From 7a0ea7d28a7a2a1cbee924d5e7723fe78259a9e4 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 13 Jan 2017 08:36:16 -0500 Subject: [PATCH] Z lift operates from standard feedhold context, ! and ~ --- g2core/canonical_machine.cpp | 163 +++++++++++++++++++---------------- g2core/controller.h | 3 + g2core/error.h | 4 +- g2core/g2core.cppproj | 4 +- g2core/plan_exec.cpp | 141 +++++++++++------------------- 5 files changed, 146 insertions(+), 169 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 47b3bafc..e3f74621 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -113,11 +113,11 @@ **** CM GLOBALS & STRUCTURE ALLOCATIONS ******************************************* ***********************************************************************************/ -cmMachineSelect cm_select; -cmMachine_t *cm; // pointer to active canonical machine -cmMachine_t cm1; // canonical machine primary machine -cmMachine_t cm2; // canonical machine secondary machine -cmToolTable_t tt; // global tool table +cmMachineSelect cm_select; // CM_PRIMARY, CM_SECONDARY, CM_SECONDARY_RETURN +cmMachine_t *cm; // pointer to active canonical machine +cmMachine_t cm1; // canonical machine primary machine +cmMachine_t cm2; // canonical machine secondary machine +cmToolTable_t tt; // global tool table /*********************************************************************************** **** GENERIC STATIC FUNCTIONS AND VARIABLES *************************************** @@ -1766,52 +1766,81 @@ stat_t cm_mto_control(const float P_word, const bool P_flag) // M50.1 * to ensure that it either arrives on the data channel or that the data channel is * empty before writing it to the control channel. */ +/* With the addition of the secondary CM, feedhold state management gets tricky. + What you see below is a temporary solution until we decide the general solution. + + The general solution causes a feedhold from the primary context to switch + into the secondary context to perform feedhold actions. When in the secondary + context an additional feedhold will perform the usual STOP operation, but + will remain in the secondary context, and therefore not perform any feedhold + actions (lifts, spindle, etc.). This is needed to support homing and probing + operations from within the secondary context. + + Oddities of the general solution: + - Should we allow a feedhold to be peformed if the tool is not moving? + Right now we don't, but with the secondary context this might be useful + + What you see here is a Q&D to only allow feedholds from the primary context. + It has the following limitations: + - Feedhold requests are only honored form the primary context + - Queue flush requests are only honored form the primary context + - Machine alarm state is not (yet) taken into account in feedhold sequencing and restart + */ + /* * cm_request_feedhold() - * cm_request_end_hold() - cycle restart + * cm_request_end_hold() * cm_request_queue_flush() + * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests */ -void cm_request_feedhold(void) { - // honor request if not already in a feedhold and you are moving - if ((cm->hold_state == FEEDHOLD_OFF) && (cm->motion_state != MOTION_STOP)) { - cm->hold_state = FEEDHOLD_REQUESTED; + +void cm_request_feedhold(void) +{ + // do not generate a feedhold request from the secondary context + if (cm_select != CM_PRIMARY) { + return; + } + // only generate request if not already in a feedhold and the machine is in motion + if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { + cm1.hold_state = FEEDHOLD_REQUESTED; } } -void cm_request_end_hold(void) +void cm_request_end_hold(void) // This is usually requested form the secondary context { - if (cm->hold_state != FEEDHOLD_OFF) { - cm->end_hold_requested = true; + if (cm1.hold_state != FEEDHOLD_OFF) { + cm1.end_hold_requested = true; } } void cm_request_queue_flush() { - if ((cm->hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold - (cm->queue_flush_state == FLUSH_OFF)) { // ...and only once - cm->queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped + // do not generate a queue flush request from the secondary context + if (cm_select != CM_PRIMARY) { + return; + } + if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold + (cm1.queue_flush_state == FLUSH_OFF)) { // ...and only once + cm1.queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped // NOTE: we used to flush the input buffers, but this is handled in xio *prior* to queue flush now } } -/* - * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests - */ stat_t cm_feedhold_sequencing_callback() { - if (cm->hold_state == FEEDHOLD_REQUESTED) { + if (cm1.hold_state == FEEDHOLD_REQUESTED) { cm_start_hold(); // feed won't run unless the machine is moving } - if (cm->hold_state == FEEDHOLD_FINALIZING) { - cm->hold_state = FEEDHOLD_HOLD; + if (cm1.hold_state == FEEDHOLD_FINALIZING) { + cm1.hold_state = FEEDHOLD_HOLD; cm_switch_to_hold(); // perform Z lift, spindle & coolant operations } - if (cm->queue_flush_state == FLUSH_REQUESTED) { + if (cm1.queue_flush_state == FLUSH_REQUESTED) { cm_queue_flush(); // queue flush won't run until runtime is idle } - if (cm->end_hold_requested) { - if (cm->queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing + if (cm1.end_hold_requested) { + if (cm1.queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing cm_end_hold(); } } @@ -1822,18 +1851,17 @@ stat_t cm_feedhold_sequencing_callback() * cm_has_hold() - return true if a hold condition exists (or a pending hold request) * cm_start_hold() - start a feedhhold by signalling the exec * cm_end_hold() - end a feedhold by returning the system to normal operation - * cm_queue_flush() - Flush planner queue and correct model positions */ bool cm_has_hold() { - return (cm->hold_state != FEEDHOLD_OFF); + return (cm1.hold_state != FEEDHOLD_OFF); } void cm_start_hold() { if (mp_has_runnable_buffer(mp)) { //+++++ // 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_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); cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } @@ -1841,43 +1869,9 @@ void cm_start_hold() void cm_end_hold() { - if (cm->hold_state == FEEDHOLD_HOLD) { - cm->end_hold_requested = false; + if (cm1.hold_state == FEEDHOLD_HOLD) { + cm1.end_hold_requested = false; cm_return_from_hold(); -// mp_exit_hold_state(); - - // State machine cases: - if (cm->machine_state == MACHINE_ALARM) { - cm_spindle_off_immediate(); - cm_coolant_off_immediate(); - - } else if (cm->motion_state == MOTION_STOP) { // && (! MACHINE_ALARM) - cm_spindle_off_immediate(); - cm_coolant_off_immediate(); - cm_cycle_end(); - - } else { // (MOTION_RUN || MOTION_PLANNING) && (! MACHINE_ALARM) - cm_cycle_start(); - cm_spindle_resume(spindle.dwell_seconds); - cm_coolant_resume(); - st_request_exec_move(); - } - } -} - -void cm_queue_flush() -{ - if (mp_runtime_is_idle()) { // can't flush planner during movement - mp_flush_planner(mp); // +++++ Active planner. Potential cleanup - - for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions - cm_set_position(axis, mp_get_runtime_absolute_position(axis)); - } - if(cm->hold_state == FEEDHOLD_HOLD) { // end feedhold if we're in one - cm_end_hold(); - } - cm->queue_flush_state = FLUSH_OFF; - qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } } @@ -1976,13 +1970,17 @@ stat_t cm_return_from_hold() // LATER: if value == true return with offset c return (STAT_COMMAND_NOT_ACCEPTED); } - // *** while still in secondary machine: - + // *** While still in secondary machine: +/* + if (cm->machine_state == MACHINE_ALARM) { + cm_spindle_off_immediate(); + cm_coolant_off_immediate(); +*/ // restart spindle (with optional dwell) // restart coolant - // perform the G30 move and queue a wait + // perform the G30 move and queue a wait float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z bool flags[] = { 0,0,0,0,0,0 }; cm_goto_g30_position(target, flags); // initiate a return move @@ -2009,20 +2007,39 @@ stat_t cm_return_from_hold_callback() mr = mp->mr; cm_select = CM_PRIMARY; -// cm_set_motion_state(MOTION_STOP); // sets active model to primary - -// mp_exit_hold_state(); - cm->hold_state = FEEDHOLD_OFF; - if (mp_has_runnable_buffer(mp)) { //+++++ + if (mp_has_runnable_buffer(mp)) { //+++++ Should MP be passed or global? cm_set_motion_state(MOTION_RUN); + cm_cycle_start(); + st_request_exec_move(); sr_request_status_report(SR_REQUEST_IMMEDIATE); } else { cm_set_motion_state(MOTION_STOP); + cm_cycle_end(); } return (STAT_OK); } +/* + * cm_queue_flush() - Flush planner queue and correct model positions + */ + +void cm_queue_flush() +{ + if (mp_runtime_is_idle()) { // can't flush planner during movement + mp_flush_planner(mp); // +++++ Active planner. Potential cleanup + + for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions + cm_set_position(axis, mp_get_runtime_absolute_position(axis)); + } + if(cm->hold_state == FEEDHOLD_HOLD) { // end feedhold if we're in one + cm_end_hold(); + } + cm->queue_flush_state = FLUSH_OFF; + qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available + } +} + /****************************** * Program Functions (4.3.10) * ******************************/ diff --git a/g2core/controller.h b/g2core/controller.h index 6d290dc2..e17ca3a9 100644 --- a/g2core/controller.h +++ b/g2core/controller.h @@ -72,6 +72,9 @@ typedef struct controllerSingleton { // main TG controller struct char out_buf[OUTPUT_BUFFER_LEN]; // output buffer char saved_buf[SAVED_BUFFER_LEN]; // save the input buffer + // Exceptions - some exceptions cannot be notified by an ER because they are in interrupts + bool exec_aline_assertion_failure; // record an exception deep inside mp_exec_aline() + magic_t magic_end; } controller_t; diff --git a/g2core/error.h b/g2core/error.h index 1a26756f..a6e346a5 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -164,10 +164,10 @@ char *get_status_message(stat_t status); #define STAT_ERROR_84 84 #define STAT_ERROR_85 85 #define STAT_ERROR_86 86 -#define STAT_ERROR_87 87 // Assertion failures - build down from 99 until they meet the system internal errors +#define STAT_EXEC_ALINE_ASSERTION_FAILURE 87 #define STAT_BUFFER_FREE_ASSERTION_FAILURE 88 #define STAT_STATE_MANAGEMENT_ASSERTION_FAILURE 89 #define STAT_CONFIG_ASSERTION_FAILURE 90 @@ -469,8 +469,8 @@ static const char stat_83[] = "83"; static const char stat_84[] = "84"; static const char stat_85[] = "85"; static const char stat_86[] = "86"; -static const char stat_87[] = "87"; +static const char stat_87[] = "mp_exec_aline() assertion failure"; static const char stat_88[] = "Buffer free assertion failure"; static const char stat_89[] = "State management assertion failure"; static const char stat_90[] = "Config assertion failure"; diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index d57acc1f..c8cc86a8 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 589762c1..13ab102b 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -315,33 +315,33 @@ stat_t mp_exec_move() /************************************************************************* * ---> Everything here fires from interrupts and must be interrupt safe * - * _exec_aline() - acceleration line main routine - * _exec_aline_head() - helper for acceleration section - * _exec_aline_body() - helper for cruise section - * _exec_aline_tail() - helper for deceleration section + * _exec_aline() - acceleration line main routine + * _exec_aline_head() - helper for acceleration section + * _exec_aline_body() - helper for cruise section + * _exec_aline_tail() - helper for deceleration section * _exec_aline_segment() - helper for running a segment * * Returns: * STAT_OK move is done * STAT_EAGAIN move is not finished - has more segments to run - * STAT_NOOP cause no operation from the steppers - do not load the move + * STAT_NOOP would cause no operation to the steppers - do not load the move * STAT_xxxxx fatal error. Ends the move and frees the bf buffer * * This routine is called from the (LO) interrupt level. The interrupt sequencing * relies on the behaviors of the routines being exactly correct. Each call to - * _exec_aline() must execute and prep *one and only one* segment. If the segment + * _exec_aline() must execute and prep **one and only one** segment. If the segment * is the not the last segment in the bf buffer the _aline() must return STAT_EAGAIN. * If it's the last segment it must return STAT_OK. If it encounters a fatal error * that would terminate the move it should return a valid error code. Failure to * obey this will introduce subtle and very difficult to diagnose bugs (trust us on this). * * Note 1: Returning STAT_OK ends the move and frees the bf buffer. - * Returning STAT_OK at this point does NOT advance position meaning any - * position error will be compensated by the next move. + * Returning STAT_OK at this point does NOT advance the position vector, + * meaning any position error will be compensated by the next move. * - * Note 2: Solves a potential race condition where the current move ends but the - * new move has not started because the previous move is still being run - * by the steppers. Planning can overwrite the new move. + * Note 2: BF/MR sequencing solves a potential race condition where the current move + * ends but the new move has not started because the previous move is still + * being run by the steppers. Planning can overwrite the new move. */ /* --- State transitions - hierarchical state machine --- * @@ -357,7 +357,7 @@ stat_t mp_exec_move() * _RUN2 - run the second part * * Important distinction to note: - * - mp_plan move() is called for every type of move + * - mp_plan move() is called for every type of move (bf block) * - mp_exec_move() is called for every type of move * - mp_exec_aline() is only called for alines */ @@ -407,17 +407,17 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Initialize all new blocks, regardless of normal or feedhold operation if (mr->block_state == BLOCK_INACTIVE) { - // too short lines have already been removed... - // so is the following code is no longer needed ++++ ash + // Zero length moves (and other too-short moves) should have already been removed... + // ...so the following code is no longer needed. // But let's still alert the condition should it ever occur if (fp_ZERO(bf->length)) { // ...looks for an actual zero here rpt_exception(STAT_PLANNER_ASSERTION_FAILURE, "mp_exec_aline() zero length move"); } // Start a new move by setting up the runtime singleton (mr) - memcpy(&mr->gm, &(bf->gm), sizeof(GCodeState_t)); // copy in the gcode model state - bf->block_state = BLOCK_ACTIVE; // note that this buffer is running - // note the planner doesn't look at block_state + memcpy(&mr->gm, &(bf->gm), sizeof(GCodeState_t)); // copy in the gcode model state + bf->block_state = BLOCK_ACTIVE; // note that this buffer is running + // note the planner doesn't look at block_state mr->block_state = BLOCK_INITIAL_ACTION; mr->section = SECTION_HEAD; mr->section_state = SECTION_NEW; @@ -426,35 +426,35 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r = mr->p; // we are now going to run the planning block mr->p = mr->p->nx; // re-use the old running block as the new planning block - // Assumptions that are required for this to work: - // entry velocity <= cruise velocity && cruise velocity >= exit velocity + // Equalities that must be true for this to work: + // entry velocity <= cruise velocity && + // cruise velocity >= exit velocity + // // Even if the move is head or tail only, cruise velocity needs to be valid. // This is because a "head" is *always* entry->cruise, and a "tail" is *always* cruise->exit, - // even if there are not other sections int he move. (This is a significant time savings.) + // even if there are not other sections in the move. (This is a significant time savings.) // Here we will check to make sure that the sections are longer than MIN_SEGMENT_TIME if ((!fp_ZERO(mr->r->head_length)) && (mr->r->head_time < MIN_SEGMENT_TIME)) { - // head_time !== body_time - // We have to compute the new body time addition. - mr->r->body_length += mr->r->head_length; - mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; - - mr->r->head_length = 0; - mr->r->head_time = 0; + // head_time !== body_time + // We have to compute the new body time addition. + mr->r->body_length += mr->r->head_length; + mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; + mr->r->head_length = 0; + mr->r->head_time = 0; } if ((!fp_ZERO(mr->r->tail_length)) && (mr->r->tail_time < MIN_SEGMENT_TIME)) { // tail_time !== body_time // We have to compute the new body time addition. mr->r->body_length += mr->r->tail_length; mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; - mr->r->tail_length = 0; mr->r->tail_time = 0; } // At this point, we've already possibly merged head and/or tail into the body. - // If the body is too "short" (brief) still, we *might* be able to add it to a head or tail. + // If the body is still too "short" (brief) we *might* be able to add it to a head or tail. // If there's still a head or a tail, we will add the body to whichever there is, maybe both. // We saved it for last since it's the most expensive. if ((!fp_ZERO(mr->r->body_length)) && (mr->r->body_time < MIN_SEGMENT_TIME)) { @@ -466,10 +466,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) float body_split = mr->r->body_length/2.0; mr->r->body_length = 0; mr->r->body_time = 0; - mr->r->head_length += body_split; mr->r->tail_length += body_split; - mr->r->head_time = (2.0 * mr->r->head_length)/(mr->entry_velocity + mr->r->cruise_velocity); mr->r->tail_time = (2.0 * mr->r->tail_length)/(mr->r->cruise_velocity + mr->r->exit_velocity); } else { @@ -477,7 +475,6 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r->tail_length += mr->r->body_length; mr->r->body_length = 0; mr->r->body_time = 0; - mr->r->tail_time = (2.0 * mr->r->tail_length)/(mr->r->cruise_velocity + mr->r->exit_velocity); } } @@ -486,13 +483,13 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r->head_length += mr->r->body_length; mr->r->body_length = 0; mr->r->body_time = 0; - mr->r->head_time = (2.0 * mr->r->head_length)/(mr->entry_velocity + mr->r->cruise_velocity); } else { // Uh oh! We have a move that's all body, and is still too short!! - // ++++ RG For now, we'll consider this impossible. - while (1); + // while (1); // ++++ RG For now, we'll consider this impossible. + cs.exec_aline_assertion_failure = true; + return (STAT_EXEC_ALINE_ASSERTION_FAILURE); } } @@ -523,27 +520,27 @@ stat_t mp_exec_aline(mpBuf_t *bf) // (4) - We have decelerated a block to some velocity > zero (needs continuation in next block) // (5) - We have decelerated a block to zero velocity // (6) - We have finished all the runtime work now we have to wait for the steppers to stop - // (7) - The steppers have stopped. No motion should occur + // (7) - The steppers have stopped. No motion should occur. ALlows hold finalization to commence // (8) - We are removing the hold state and there is queued motion (handled outside this routine) // (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) if (cm->motion_state == MOTION_HOLD) { // Case (7) - all motion has ceased - if (cm->hold_state >= FEEDHOLD_FINALIZING) { // FINALIZING or FEEDHOLD_HOLD - return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement + if (cm->hold_state >= FEEDHOLD_FINALIZING) { // FEEDHOLD_FINALIZING or FEEDHOLD_HOLD + return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } // Case (6) - wait for the steppers to stop if (cm->hold_state == FEEDHOLD_PENDING) { if (mp_runtime_is_idle()) { // wait for the steppers to actually clear out if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { - // when homing, we don't need to stay in HOLD + // when homing or probing we don't want to stay in HOLD or execute finalizations cm->hold_state = FEEDHOLD_OFF; } else { cm->hold_state = FEEDHOLD_FINALIZING; } mp_zero_segment_velocity(); // for reporting purposes - sr_request_status_report(SR_REQUEST_IMMEDIATE); // was SR_REQUEST_TIMED + sr_request_status_report(SR_REQUEST_IMMEDIATE); cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE } return (STAT_OK); // hold here. No more movement @@ -552,28 +549,24 @@ 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 + 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 - + //bf->entry_vmax = 0; // set bp+0 as hold point cm->hold_state = FEEDHOLD_PENDING; // No point bothering with the rest of this move if homing or probing if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { mp_free_run_buffer(); } - mp_replan_queue(mp_get_r()); // make it replan all the blocks -// mp_replan_queue(mb.r); // make it replan all the blocks - return (STAT_OK); } // Cases (1a, 1b), Case (2), Case (4) // Build a tail-only move from here. Decelerate as fast as possible in the space we have. if ((cm->hold_state == FEEDHOLD_SYNC) || - ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { + ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { // Case (3a) - already decelerating, continue the deceleration. if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are @@ -587,13 +580,10 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Small exception, if we *just started* the head, then we're not actually accelerating yet. } else if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { mr->entry_velocity = mr->segment_velocity; - mr->section = SECTION_TAIL; mr->section_state = SECTION_NEW; - mr->r->head_length = 0; mr->r->body_length = 0; - float available_length = get_axis_vector_length(mr->target, mr->position); mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length @@ -615,7 +605,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) } } } - + // End Feedhold Processing + mr->block_state = BLOCK_ACTIVE; // NB: from this point on the contents of the bf buffer do not affect execution @@ -649,19 +640,18 @@ stat_t mp_exec_aline(mpBuf_t *bf) // There is no fourth thing. Nobody expects the Spanish Inquisition if (status == STAT_EAGAIN) { - sr_request_status_report(SR_REQUEST_TIMED); // continue reporting mr buffer - // Note that tha'll happen in a lower interrupt level. + sr_request_status_report(SR_REQUEST_TIMED); // continue reporting mr buffer + // Note that that'll happen in a lower interrupt level. } else { - mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer (reset) + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer (reset) mr->section_state = SECTION_OFF; - mp->run_time_remaining = 0.0; // it's done, so time goes to zero - - mr->entry_velocity = mr->r->exit_velocity; // feed the old exit into the entry. + mp->run_time_remaining = 0.0; // it's done, so time goes to zero + mr->entry_velocity = mr->r->exit_velocity; // feed the old exit into the entry. if (bf->block_state == BLOCK_ACTIVE) { - if (mp_free_run_buffer()) { // returns true of the buffer is empty + if (mp_free_run_buffer()) { // returns true of the buffer is empty if (cm->hold_state == FEEDHOLD_OFF) { - cm_cycle_end(); // free buffer & end cycle if planner is empty + cm_cycle_end(); // free buffer & end cycle if planner is empty } } else { st_request_forward_plan(); @@ -671,38 +661,6 @@ 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 - * - * Feedhold is executed as cm->hold_state transitions executed inside _exec_aline() - * Invoke a feedhold by calling cm_request_hold() or cm_start_hold() directly - * Return from feedhold by calling cm_request_end_hold() or cm_end_hold directly. - * See canonical_macine.c for a more detailed explanation of feedhold operation. - */ -/* -void mp_exit_hold_state() -{ - cm->hold_state = FEEDHOLD_OFF; - if (mp_has_runnable_buffer(mp)) { //+++++ - cm_set_motion_state(MOTION_RUN); - sr_request_status_report(SR_REQUEST_IMMEDIATE); - } else { - cm_set_motion_state(MOTION_STOP); - } -} -*/ - /* * Forward difference math explained: * @@ -836,7 +794,6 @@ static void _init_forward_diffs(const float v_0, const float v_1) // E = 0 // F = Vi - const float h = 1/(mr->segments); const float h_2 = h * h; const float h_3 = h_2 * h;