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.
|
||||
#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
|
||||
// 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
|
||||
|
@ -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.
|
||||
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; }
|
||||
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
|
||||
// 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_BUILD "20140804"
|
||||
#define GRBL_VERSION_BUILD "20140805"
|
||||
|
||||
// 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
|
||||
|
30
stepper.c
30
stepper.c
@ -637,7 +637,6 @@ void st_prep_buffer()
|
||||
prep.maximum_speed = prep.exit_speed;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Initialize new segment
|
||||
@ -688,6 +687,8 @@ void st_prep_buffer()
|
||||
break;
|
||||
case RAMP_CRUISE:
|
||||
// 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;
|
||||
if (mm_var < prep.decelerate_after) { // End of cruise.
|
||||
// Cruise-deceleration junction or end of block.
|
||||
@ -853,30 +854,3 @@ void st_prep_buffer()
|
||||
return 0.0f;
|
||||
}
|
||||
#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