From b332d6edbba7b147fba7be4779a68a44ad9c5df1 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 19 Feb 2014 07:21:40 -0700 Subject: [PATCH] Commenting updates. Minor bug fix with exit of soft limit event. --- limits.c | 4 ++-- motion_control.c | 21 ++++++++++++--------- stepper.c | 28 +++++++++++++++------------- system.c | 4 ++-- system.h | 12 ++++++------ 5 files changed, 37 insertions(+), 32 deletions(-) diff --git a/limits.c b/limits.c index 9016e8a..1660ec4 100644 --- a/limits.c +++ b/limits.c @@ -190,7 +190,7 @@ void limits_go_home(uint8_t cycle_mask) if (sys.execute & EXEC_RESET) { protocol_execute_runtime(); return; } } while (STEP_MASK & axislock); - st_reset(); // Force disable steppers and reset step segment buffer. Ensure homing motion is cleared. + st_reset(); // Immediately force kill steppers and reset step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure homing motion is cleared. delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate. @@ -255,7 +255,7 @@ void limits_soft_check(float *target) do { protocol_execute_runtime(); if (sys.abort) { return; } - } while (sys.state == STATE_HOLD); + } while ( sys.state != STATE_IDLE || sys.state != STATE_QUEUED); } mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. diff --git a/motion_control.c b/motion_control.c index b3711a9..f9b1c7b 100644 --- a/motion_control.c +++ b/motion_control.c @@ -48,16 +48,19 @@ void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate) // If in check gcode mode, prevent motion by blocking planner. Soft limits still work. if (sys.state == STATE_CHECK_MODE) { return; } - // TODO: Backlash compensation may be installed here. Only need direction info to track when - // to insert a backlash line motion(s) before the intended line motion. Requires its own + // NOTE: Backlash compensation may be installed here. It will need direction info to track when + // to insert a backlash line motion(s) before the intended line motion and will require its own // plan_check_full_buffer() and check for system abort loop. Also for position reporting - // backlash steps will need to be also tracked. Not sure what the best strategy is for this, - // i.e. keep the planner independent and do the computations in the status reporting, or let - // the planner handle the position corrections. The latter may get complicated. - // TODO: Backlash comp positioning values may need to be kept at a system level, i.e. tracking - // true position after a feed hold in the middle of a backlash move. The difficulty is in making - // sure that the stepper subsystem and planner are working in sync, and the status report - // position also takes this into account. + // backlash steps will need to be also tracked, which will need to be kept at a system level. + // There are likely some other things that will need to be tracked as well. However, we feel + // that backlash compensation should NOT be handled by Grbl itself, because there are a myriad + // of ways to implement it and can be effective or ineffective for different CNC machines. This + // would be better handled by the interface as a post-processor task, where the original g-code + // is translated and inserts backlash motions that best suits the machine. + // NOTE: Perhaps as a middle-ground, all that needs to be sent is a flag or special command that + // indicates to Grbl what is a backlash compensation motion, so that Grbl executes the move but + // doesn't update the machine position values. Since the position values used by the g-code + // parser and planner are separate from the system machine positions, this is doable. // If the buffer is full: good! That means we are well ahead of the robot. // Remain in this loop until there is room in the buffer. diff --git a/stepper.c b/stepper.c index 54a6ecb..bfe1f74 100644 --- a/stepper.c +++ b/stepper.c @@ -541,7 +541,7 @@ void st_prep_buffer() // Initialize segment buffer data for generating the segments. prep.steps_remaining = pl_block->step_event_count; prep.step_per_mm = prep.steps_remaining/pl_block->millimeters; - prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR*pl_block->millimeters/prep.steps_remaining; + prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR/prep.step_per_mm; prep.dt_remainder = 0.0; // Reset for new planner block @@ -639,8 +639,8 @@ void st_prep_buffer() float time_var = dt_max; // Time worker variable float mm_var; // mm-Distance worker variable float speed_var; // Speed worker variable - float mm_remaining = pl_block->millimeters; - float minimum_mm = pl_block->millimeters-prep.req_mm_increment; + float mm_remaining = pl_block->millimeters; // New segment distance from end of block. + float minimum_mm = mm_remaining-prep.req_mm_increment; // Guarantee at least one step. if (minimum_mm < 0.0) { minimum_mm = 0.0; } do { @@ -691,7 +691,9 @@ void st_prep_buffer() if (dt < dt_max) { time_var = dt_max - dt; } // **Incomplete** At ramp junction. else { if (mm_remaining > minimum_mm) { // Check for very slow segments with zero steps. - dt_max += DT_SEGMENT; // Increase segment time to ensure at least one step in segment. + // Increase segment time to ensure at least one step in segment. Override and loop + // through distance calculations until minimum_mm or mm_complete. + dt_max += DT_SEGMENT; time_var = dt_max - dt; } else { break; // **Complete** Exit loop. Segment execution time maxed. @@ -716,8 +718,9 @@ void st_prep_buffer() prep_segment->n_step = last_n_steps_remaining-n_steps_remaining; // Compute number of steps to execute. // Bail if we are at the end of a feed hold and don't have a step to execute. - if (sys.state == STATE_HOLD) { - if (prep_segment->n_step == 0) { + if (prep_segment->n_step == 0) { + if (sys.state == STATE_HOLD) { + // Less than one step to decelerate to zero speed, but already very close. AMASS // requires full steps to execute. So, just bail. prep.current_speed = 0.0; @@ -776,7 +779,11 @@ void st_prep_buffer() } #endif - // Determine end of segment conditions. Setup initial conditions for next segment. + // Segment complete! Increment segment buffer indices. + segment_buffer_head = segment_next_head; + if ( ++segment_next_head == SEGMENT_BUFFER_SIZE ) { segment_next_head = 0; } + + // Setup initial conditions for next segment. if (mm_remaining > prep.mm_complete) { // Normal operation. Block incomplete. Distance remaining in block to be executed. pl_block->millimeters = mm_remaining; @@ -793,6 +800,7 @@ void st_prep_buffer() plan_cycle_reinitialize(); sys.state = STATE_QUEUED; // End cycle. + return; // Bail! // TODO: Try to move QUEUED setting into cycle re-initialize. } else { // End of planner block @@ -802,12 +810,6 @@ void st_prep_buffer() } } - // New step segment initialization completed. Increment segment buffer indices. - segment_buffer_head = segment_next_head; - if ( ++segment_next_head == SEGMENT_BUFFER_SIZE ) { segment_next_head = 0; } - - if (sys.state == STATE_QUEUED) { return; } // Bail if hold completes - // int32_t blength = segment_buffer_head - segment_buffer_tail; // if (blength < 0) { blength += SEGMENT_BUFFER_SIZE; } // printInteger(blength); diff --git a/system.c b/system.c index 229203f..110fa82 100644 --- a/system.c +++ b/system.c @@ -150,7 +150,7 @@ uint8_t system_execute_line(char *line) } else { report_build_info(line); } - } else { // Store startup line + } else { // Store startup line [IDLE/ALARM] if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); } helper_var = char_counter; // Set helper variable as counter to start of user info line. do { @@ -169,7 +169,7 @@ uint8_t system_execute_line(char *line) } } break; - } else { // Store startup line + } else { // Store startup line [IDLE Only] Prevents motion during ALARM. if (sys.state != STATE_IDLE) { return(STATUS_IDLE_ERROR); } // Store only when idle. helper_var = true; // Set helper_var to flag storing method. // No break. Continues into default: to read remaining command characters. diff --git a/system.h b/system.h index 78faa5c..12d8965 100644 --- a/system.h +++ b/system.h @@ -59,12 +59,12 @@ // of Grbl to manage each without overlapping. It is also used as a messaging flag for // critical events. #define STATE_IDLE 0 // Must be zero. No flags. -#define STATE_QUEUED bit(0) // Indicates buffered blocks, awaiting cycle start. -#define STATE_CYCLE bit(1) // Cycle is running -#define STATE_HOLD bit(2) // Executing feed hold -#define STATE_HOMING bit(3) // Performing homing cycle -#define STATE_ALARM bit(4) // In alarm state. Locks out all g-code processes. Allows settings access. -#define STATE_CHECK_MODE bit(5) // G-code check mode. Locks out planner and motion only. +#define STATE_ALARM bit(0) // In alarm state. Locks out all g-code processes. Allows settings access. +#define STATE_CHECK_MODE bit(1) // G-code check mode. Locks out planner and motion only. +#define STATE_HOMING bit(2) // Performing homing cycle +#define STATE_QUEUED bit(3) // Indicates buffered blocks, awaiting cycle start. +#define STATE_CYCLE bit(4) // Cycle is running +#define STATE_HOLD bit(5) // Executing feed hold // #define STATE_JOG bit(6) // Jogging mode is unique like homing. // Define global system variables