Parking motion bug fix.
- Parking motion would intermittently complete the queued tool path upon resuming in certain scenarios. Now fixed.
This commit is contained in:
		
							
								
								
									
										62
									
								
								grbl/gcode.c
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								grbl/gcode.c
									
									
									
									
									
								
							| @@ -1034,37 +1034,37 @@ uint8_t gc_execute_line(char *line) | ||||
|   // refill and can only be resumed by the cycle start run-time command. | ||||
|   gc_state.modal.program_flow = gc_block.modal.program_flow; | ||||
|   if (gc_state.modal.program_flow) {  | ||||
| 	protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on. | ||||
| 	if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) { | ||||
| 	  if (sys.state != STATE_CHECK_MODE) { | ||||
| 		bit_true_atomic(sys.rt_exec_state, EXEC_FEED_HOLD); // Use feed hold for program pause. | ||||
| 		protocol_execute_realtime(); // Execute suspend. | ||||
| 	  } | ||||
| 	} else { // == PROGRAM_FLOW_COMPLETED | ||||
| 	  // Upon program complete, only a subset of g-codes reset to certain defaults, according to  | ||||
| 	  // LinuxCNC's program end descriptions and testing. Only modal groups [G-code 1,2,3,5,7,12] | ||||
| 	  // and [M-code 7,8,9] reset to [G1,G17,G90,G94,G40,G54,M5,M9,M48]. The remaining modal groups | ||||
| 	  // [G-code 4,6,8,10,13,14,15] and [M-code 4,5,6] and the modal words [F,S,T,H] do not reset. | ||||
| 	  gc_state.modal.motion = MOTION_MODE_LINEAR; | ||||
| 	  gc_state.modal.plane_select = PLANE_SELECT_XY; | ||||
| 	  gc_state.modal.distance = DISTANCE_MODE_ABSOLUTE; | ||||
| 	  gc_state.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN; | ||||
| 	  // gc_state.modal.cutter_comp = CUTTER_COMP_DISABLE; // Not supported. | ||||
| 	  gc_state.modal.coord_select = 0; // G54 | ||||
| 	  gc_state.modal.spindle = SPINDLE_DISABLE; | ||||
| 	  gc_state.modal.coolant = COOLANT_DISABLE; | ||||
| 	  // gc_state.modal.override = OVERRIDE_DISABLE; // Not supported. | ||||
| 	   | ||||
| 	  // Execute coordinate change and spindle/coolant stop. | ||||
| 	  if (sys.state != STATE_CHECK_MODE) { | ||||
| 		if (!(settings_read_coord_data(gc_state.modal.coord_select,coordinate_data))) { FAIL(STATUS_SETTING_READ_FAIL); }  | ||||
| 		memcpy(gc_state.coord_system,coordinate_data,sizeof(coordinate_data)); | ||||
| 		spindle_stop(); | ||||
| 		coolant_stop();		 | ||||
| 	  } | ||||
| 	   | ||||
| 	  report_feedback_message(MESSAGE_PROGRAM_END); | ||||
| 	} | ||||
|     protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on. | ||||
|     if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) { | ||||
|       if (sys.state != STATE_CHECK_MODE) { | ||||
|         bit_true_atomic(sys.rt_exec_state, EXEC_FEED_HOLD); // Use feed hold for program pause. | ||||
|         protocol_execute_realtime(); // Execute suspend. | ||||
|       } | ||||
|     } else { // == PROGRAM_FLOW_COMPLETED | ||||
|       // Upon program complete, only a subset of g-codes reset to certain defaults, according to  | ||||
|       // LinuxCNC's program end descriptions and testing. Only modal groups [G-code 1,2,3,5,7,12] | ||||
|       // and [M-code 7,8,9] reset to [G1,G17,G90,G94,G40,G54,M5,M9,M48]. The remaining modal groups | ||||
|       // [G-code 4,6,8,10,13,14,15] and [M-code 4,5,6] and the modal words [F,S,T,H] do not reset. | ||||
|       gc_state.modal.motion = MOTION_MODE_LINEAR; | ||||
|       gc_state.modal.plane_select = PLANE_SELECT_XY; | ||||
|       gc_state.modal.distance = DISTANCE_MODE_ABSOLUTE; | ||||
|       gc_state.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN; | ||||
|       // gc_state.modal.cutter_comp = CUTTER_COMP_DISABLE; // Not supported. | ||||
|       gc_state.modal.coord_select = 0; // G54 | ||||
|       gc_state.modal.spindle = SPINDLE_DISABLE; | ||||
|       gc_state.modal.coolant = COOLANT_DISABLE; | ||||
|       // gc_state.modal.override = OVERRIDE_DISABLE; // Not supported. | ||||
|      | ||||
|       // Execute coordinate change and spindle/coolant stop. | ||||
|       if (sys.state != STATE_CHECK_MODE) { | ||||
|         if (!(settings_read_coord_data(gc_state.modal.coord_select,coordinate_data))) { FAIL(STATUS_SETTING_READ_FAIL); }  | ||||
|         memcpy(gc_state.coord_system,coordinate_data,sizeof(coordinate_data)); | ||||
|         spindle_stop(); | ||||
|         coolant_stop();		 | ||||
|       } | ||||
|      | ||||
|       report_feedback_message(MESSAGE_PROGRAM_END); | ||||
|     } | ||||
|     gc_state.modal.program_flow = PROGRAM_FLOW_RUNNING; // Reset program flow. | ||||
|   } | ||||
|      | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
|  | ||||
| // Grbl versioning system | ||||
| #define GRBL_VERSION "1.0b" | ||||
| #define GRBL_VERSION_BUILD "20150829" | ||||
| #define GRBL_VERSION_BUILD "20150902" | ||||
|  | ||||
| // Define standard libraries used by Grbl. | ||||
| #include <avr/io.h> | ||||
|   | ||||
| @@ -72,10 +72,10 @@ uint8_t limits_get_state() | ||||
|   uint8_t pin = (LIMIT_PIN & LIMIT_MASK); | ||||
|   if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { pin ^= LIMIT_MASK; } | ||||
|   if (pin) {   | ||||
| 	uint8_t idx; | ||||
| 	for (idx=0; idx<N_AXIS; idx++) { | ||||
| 	  if (pin & get_limit_pin_mask(idx)) { limit_state |= (1 << idx); } | ||||
| 	} | ||||
|     uint8_t idx; | ||||
|     for (idx=0; idx<N_AXIS; idx++) { | ||||
|       if (pin & get_limit_pin_mask(idx)) { limit_state |= (1 << idx); } | ||||
|     } | ||||
|   } | ||||
|   return(limit_state); | ||||
| } | ||||
| @@ -210,37 +210,37 @@ void limits_go_home(uint8_t cycle_mask) | ||||
|      | ||||
|     st_prep_buffer(); // Prep and fill segment buffer from newly planned block. | ||||
|     st_wake_up(); // Initiate motion | ||||
| 	do { | ||||
| 	  if (approach) { | ||||
| 		// Check limit state. Lock out cycle axes when they change. | ||||
| 		limit_state = limits_get_state(); | ||||
| 		for (idx=0; idx<N_AXIS; idx++) { | ||||
| 		  if (axislock & step_pin[idx]) { | ||||
| 			if (limit_state & (1 << idx)) { axislock &= ~(step_pin[idx]); } | ||||
| 		  } | ||||
| 		} | ||||
| 		sys.homing_axis_lock = axislock; | ||||
| 	  } | ||||
|     do { | ||||
|       if (approach) { | ||||
|         // Check limit state. Lock out cycle axes when they change. | ||||
|         limit_state = limits_get_state(); | ||||
|         for (idx=0; idx<N_AXIS; idx++) { | ||||
|           if (axislock & step_pin[idx]) { | ||||
|             if (limit_state & (1 << idx)) { axislock &= ~(step_pin[idx]); } | ||||
|           } | ||||
|         } | ||||
|         sys.homing_axis_lock = axislock; | ||||
|       } | ||||
|  | ||||
| 	  st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. | ||||
|       st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. | ||||
|  | ||||
| 	  // Exit routines: No time to run protocol_execute_realtime() in this loop. | ||||
| 	  if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) { | ||||
| 	    // Homing failure: Limit switches are still engaged after pull-off motion | ||||
| 		if ( (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET)) ||  // Safety door or reset issued | ||||
| 		     (!approach && (limits_get_state() & cycle_mask)) ||  // Limit switch still engaged after pull-off motion | ||||
| 		     ( approach && (sys.rt_exec_state & EXEC_CYCLE_STOP)) ) { // Limit switch not found during approach. | ||||
|      	  mc_reset(); // Stop motors, if they are running. | ||||
| 		  protocol_execute_realtime(); | ||||
| 		  return; | ||||
| 		} else { | ||||
| 		  // Pull-off motion complete. Disable CYCLE_STOP from executing. | ||||
|       // Exit routines: No time to run protocol_execute_realtime() in this loop. | ||||
|       if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) { | ||||
|         // Homing failure: Limit switches are still engaged after pull-off motion | ||||
|         if ( (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET)) ||  // Safety door or reset issued | ||||
|            (!approach && (limits_get_state() & cycle_mask)) ||  // Limit switch still engaged after pull-off motion | ||||
|            ( approach && (sys.rt_exec_state & EXEC_CYCLE_STOP)) ) { // Limit switch not found during approach. | ||||
|           mc_reset(); // Stop motors, if they are running. | ||||
|           protocol_execute_realtime(); | ||||
|           return; | ||||
|         } else { | ||||
|           // Pull-off motion complete. Disable CYCLE_STOP from executing. | ||||
|           bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_STOP); | ||||
| 		  break; | ||||
| 		}  | ||||
| 	  } | ||||
|           break; | ||||
|         }  | ||||
|       } | ||||
|  | ||||
| 	} while (STEP_MASK & axislock); | ||||
|     } while (STEP_MASK & axislock); | ||||
|  | ||||
|     st_reset(); // Immediately force kill steppers and reset step segment buffer. | ||||
|     plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. | ||||
|   | ||||
| @@ -135,7 +135,6 @@ typedef struct { | ||||
|     uint8_t last_st_block_index; | ||||
|     float last_steps_remaining; | ||||
|     float last_step_per_mm; | ||||
|     float last_req_mm_increment; | ||||
|     float last_dt_remainder; | ||||
|   #endif | ||||
|  | ||||
| @@ -551,12 +550,13 @@ static uint8_t st_next_block_index(uint8_t block_index) | ||||
|   {    | ||||
|     // Restore step execution data and flags of partially completed block, if necessary.  | ||||
|     if (prep.recalculate_flag & PREP_FLAG_HOLD_PARTIAL_BLOCK) { | ||||
|       st_prep_block = &st_block_buffer[prep.last_st_block_index]; | ||||
|       prep.st_block_index = prep.last_st_block_index; | ||||
|       prep.steps_remaining = prep.last_steps_remaining; | ||||
|       prep.dt_remainder = prep.last_dt_remainder; | ||||
|       prep.step_per_mm = prep.last_step_per_mm; | ||||
|       st_prep_block = &st_block_buffer[prep.st_block_index]; | ||||
|       prep.recalculate_flag = (PREP_FLAG_HOLD_PARTIAL_BLOCK | PREP_FLAG_RECALCULATE); | ||||
|       prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR/prep.step_per_mm; // Recompute this value. | ||||
|     } else { | ||||
|       prep.recalculate_flag = false; | ||||
|     } | ||||
| @@ -594,12 +594,15 @@ void st_prep_buffer() | ||||
|         if (sys.step_control & STEP_CONTROL_EXECUTE_PARK) { pl_block = plan_get_parking_block(); } | ||||
|         else { pl_block = plan_get_current_block(); } | ||||
|         if (pl_block == NULL) { return; } // No planner blocks. Exit. | ||||
|    | ||||
|  | ||||
|         // Check if we need to only recompute the velocity profile or load a new block. | ||||
|         if (prep.recalculate_flag & PREP_FLAG_RECALCULATE) { | ||||
|  | ||||
|           if (prep.recalculate_flag & PREP_FLAG_PARKING) { prep.recalculate_flag &= ~(PREP_FLAG_RECALCULATE); } | ||||
|           else { prep.recalculate_flag = false; } | ||||
|        | ||||
|  | ||||
|         } else { | ||||
|  | ||||
|       #else | ||||
|        | ||||
|         // Query planner for a queued block | ||||
| @@ -608,11 +611,12 @@ void st_prep_buffer() | ||||
|  | ||||
|         // Check if we need to only recompute the velocity profile or load a new block. | ||||
|         if (prep.recalculate_flag & PREP_FLAG_RECALCULATE) { | ||||
|  | ||||
|           prep.recalculate_flag = false; | ||||
|          | ||||
|         } else { | ||||
| 	       | ||||
|       #endif | ||||
|  | ||||
|       } else { | ||||
|                | ||||
|         // Load the Bresenham stepping data for the block. | ||||
|         prep.st_block_index = st_next_block_index(prep.st_block_index); | ||||
| @@ -639,7 +643,7 @@ void st_prep_buffer() | ||||
|         prep.step_per_mm = prep.steps_remaining/pl_block->millimeters; | ||||
|         prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR/prep.step_per_mm; | ||||
|         prep.dt_remainder = 0.0; // Reset for new segment block | ||||
|  | ||||
|        | ||||
|         if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { | ||||
|           // New block loaded mid-hold. Override planner block entry speed to enforce deceleration. | ||||
|           prep.current_speed = prep.exit_speed;  | ||||
| @@ -648,7 +652,7 @@ void st_prep_buffer() | ||||
|           prep.current_speed = sqrt(pl_block->entry_speed_sqr);  | ||||
|         } | ||||
|       } | ||||
|  | ||||
|        | ||||
| 			/* ---------------------------------------------------------------------------------  | ||||
| 			 Compute the velocity profile of a new planner block based on its entry and exit | ||||
| 			 speeds, or recompute the profile of a partially-completed planner block if the  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user