Fixed bug related to very very low feed rates.
- A very very low feed rate command like `G1 X100 F0.01` would cause some floating-point round-off error and freeze Grbl into an infinite loop. To fix it, introduced a MINIMUM_FEED_RATE parameter in config.h to ensure motions always complete. - MINIMUM_FEED_RATE is set at 1.0 mm/min by default. It’s recommended that no rates are below this value, but 0.1mm/min may be ok in some situations.
This commit is contained in:
parent
955a9f3cf8
commit
9b9abf1b2f
5
config.h
5
config.h
@ -167,6 +167,11 @@
|
|||||||
// should not be much greater than zero or to the minimum value necessary for the machine to work.
|
// should not be much greater than zero or to the minimum value necessary for the machine to work.
|
||||||
#define MINIMUM_JUNCTION_SPEED 0.0 // (mm/min)
|
#define MINIMUM_JUNCTION_SPEED 0.0 // (mm/min)
|
||||||
|
|
||||||
|
// Sets the minimum feed rate the planner will allow. Any value below it will be set to this minimum
|
||||||
|
// value. This also ensures that a planned motion always completes and accounts for any floating-point
|
||||||
|
// round-off errors. Recommend a value no lower than 1.0.
|
||||||
|
#define MINIMUM_FEED_RATE 1.0 // (mm/min)
|
||||||
|
|
||||||
// Number of arc generation iterations by small angle approximation before exact arc trajectory
|
// Number of arc generation iterations by small angle approximation before exact arc trajectory
|
||||||
// correction with expensive sin() and cos() calcualtions. This parameter maybe decreased if there
|
// correction with expensive sin() and cos() calcualtions. This parameter maybe decreased if there
|
||||||
// are issues with the accuracy of the arc generations, or increased if arc execution is getting
|
// are issues with the accuracy of the arc generations, or increased if arc execution is getting
|
||||||
|
@ -309,6 +309,7 @@ uint8_t plan_check_full_buffer()
|
|||||||
// TODO: Need to distinguish a rapids vs feed move for overrides. Some flag of some sort.
|
// TODO: Need to distinguish a rapids vs feed move for overrides. Some flag of some sort.
|
||||||
if (feed_rate < 0) { feed_rate = SOME_LARGE_VALUE; } // Scaled down to absolute max/rapids rate later
|
if (feed_rate < 0) { feed_rate = SOME_LARGE_VALUE; } // Scaled down to absolute max/rapids rate later
|
||||||
else if (invert_feed_rate) { feed_rate = block->millimeters/feed_rate; }
|
else if (invert_feed_rate) { feed_rate = block->millimeters/feed_rate; }
|
||||||
|
if (feed_rate < MINIMUM_FEED_RATE) { feed_rate = MINIMUM_FEED_RATE; } // Prevents step generation round-off condition.
|
||||||
|
|
||||||
// Calculate the unit vector of the line move and the block maximum feed rate and acceleration scaled
|
// Calculate the unit vector of the line move and the block maximum feed rate and acceleration scaled
|
||||||
// down such that no individual axes maximum values are exceeded with respect to the line direction.
|
// down such that no individual axes maximum values are exceeded with respect to the line direction.
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define GRBL_VERSION "0.9g"
|
#define GRBL_VERSION "0.9g"
|
||||||
#define GRBL_VERSION_BUILD "20140804"
|
#define GRBL_VERSION_BUILD "20140805"
|
||||||
|
|
||||||
// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
|
// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
|
||||||
// when firmware is upgraded. Always stored in byte 0 of eeprom
|
// when firmware is upgraded. Always stored in byte 0 of eeprom
|
||||||
|
30
stepper.c
30
stepper.c
@ -637,7 +637,6 @@ void st_prep_buffer()
|
|||||||
prep.maximum_speed = prep.exit_speed;
|
prep.maximum_speed = prep.exit_speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize new segment
|
// Initialize new segment
|
||||||
@ -688,6 +687,8 @@ void st_prep_buffer()
|
|||||||
break;
|
break;
|
||||||
case RAMP_CRUISE:
|
case RAMP_CRUISE:
|
||||||
// NOTE: mm_var used to retain the last mm_remaining for incomplete segment time_var calculations.
|
// NOTE: mm_var used to retain the last mm_remaining for incomplete segment time_var calculations.
|
||||||
|
// NOTE: If maximum_speed*time_var value is too low, round-off can cause mm_var to not change. To
|
||||||
|
// prevent this, simply enforce a minimum speed threshold in the planner.
|
||||||
mm_var = mm_remaining - prep.maximum_speed*time_var;
|
mm_var = mm_remaining - prep.maximum_speed*time_var;
|
||||||
if (mm_var < prep.decelerate_after) { // End of cruise.
|
if (mm_var < prep.decelerate_after) { // End of cruise.
|
||||||
// Cruise-deceleration junction or end of block.
|
// Cruise-deceleration junction or end of block.
|
||||||
@ -853,30 +854,3 @@ void st_prep_buffer()
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
TODO: With feedrate overrides, increases to the override value will not significantly
|
|
||||||
change the current planner and stepper operation. When the value increases, we simply
|
|
||||||
need to recompute the block plan with new nominal speeds and maximum junction velocities.
|
|
||||||
However with a decreasing feedrate override, this gets a little tricky. The current block
|
|
||||||
plan is optimal, so if we try to reduce the feed rates, it may be impossible to create
|
|
||||||
a feasible plan at its current operating speed and decelerate down to zero at the end of
|
|
||||||
the buffer. We first have to enforce a deceleration to meet and intersect with the reduced
|
|
||||||
feedrate override plan. For example, if the current block is cruising at a nominal rate
|
|
||||||
and the feedrate override is reduced, the new nominal rate will now be lower. The velocity
|
|
||||||
profile must first decelerate to the new nominal rate and then follow on the new plan.
|
|
||||||
Another issue is whether or not a feedrate override reduction causes a deceleration
|
|
||||||
that acts over several planner blocks. For example, say that the plan is already heavily
|
|
||||||
decelerating throughout it, reducing the feedrate override will not do much to it. So,
|
|
||||||
how do we determine when to resume the new plan? One solution is to tie into the feed hold
|
|
||||||
handling code to enforce a deceleration, but check when the current speed is less than or
|
|
||||||
equal to the block maximum speed and is in an acceleration or cruising ramp. At this
|
|
||||||
point, we know that we can recompute the block velocity profile to meet and continue onto
|
|
||||||
the new block plan.
|
|
||||||
One "easy" way to do this is to have the step segment buffer enforce a deceleration and
|
|
||||||
continually re-plan the planner buffer until the plan becomes feasible. This can work
|
|
||||||
and may be easy to implement, but it expends a lot of CPU cycles and may block out the
|
|
||||||
rest of the functions from operating at peak efficiency. Still the question is how do
|
|
||||||
we know when the plan is feasible in the context of what's already in the code and not
|
|
||||||
require too much more code?
|
|
||||||
*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user