|
@@ -28,12 +28,14 @@
|
28
|
28
|
* Derived from Grbl
|
29
|
29
|
* Copyright (c) 2009-2011 Simen Svale Skogsrud
|
30
|
30
|
*
|
31
|
|
- * The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis.
|
|
31
|
+ * Ring buffer gleaned from wiring_serial library by David A. Mellis.
|
32
|
32
|
*
|
|
33
|
+ * Fast inverse function needed for Bézier interpolation for AVR
|
|
34
|
+ * was designed, written and tested by Eduardo José Tagle, April 2018.
|
33
|
35
|
*
|
34
|
|
- * Reasoning behind the mathematics in this module (in the key of 'Mathematica'):
|
|
36
|
+ * Planner mathematics (Mathematica-style):
|
35
|
37
|
*
|
36
|
|
- * s == speed, a == acceleration, t == time, d == distance
|
|
38
|
+ * Where: s == speed, a == acceleration, t == time, d == distance
|
37
|
39
|
*
|
38
|
40
|
* Basic definitions:
|
39
|
41
|
* Speed[s_, a_, t_] := s + (a*t)
|
|
@@ -41,7 +43,7 @@
|
41
|
43
|
*
|
42
|
44
|
* Distance to reach a specific speed with a constant acceleration:
|
43
|
45
|
* Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, d, t]
|
44
|
|
- * d -> (m^2 - s^2)/(2 a) --> estimate_acceleration_distance()
|
|
46
|
+ * d -> (m^2 - s^2) / (2 a)
|
45
|
47
|
*
|
46
|
48
|
* Speed after a given distance of travel with constant acceleration:
|
47
|
49
|
* Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, m, t]
|
|
@@ -49,17 +51,18 @@
|
49
|
51
|
*
|
50
|
52
|
* DestinationSpeed[s_, a_, d_] := Sqrt[2 a d + s^2]
|
51
|
53
|
*
|
52
|
|
- * When to start braking (di) to reach a specified destination speed (s2) after accelerating
|
53
|
|
- * from initial speed s1 without ever stopping at a plateau:
|
|
54
|
+ * When to start braking (di) to reach a specified destination speed (s2) after
|
|
55
|
+ * acceleration from initial speed s1 without ever reaching a plateau:
|
54
|
56
|
* Solve[{DestinationSpeed[s1, a, di] == DestinationSpeed[s2, a, d - di]}, di]
|
55
|
|
- * di -> (2 a d - s1^2 + s2^2)/(4 a) --> intersection_distance()
|
|
57
|
+ * di -> (2 a d - s1^2 + s2^2)/(4 a)
|
56
|
58
|
*
|
57
|
|
- * IntersectionDistance[s1_, s2_, a_, d_] := (2 a d - s1^2 + s2^2)/(4 a)
|
|
59
|
+ * We note, as an optimization, that if we have already calculated an
|
|
60
|
+ * acceleration distance d1 from s1 to m and a deceration distance d2
|
|
61
|
+ * from m to s2 then
|
58
|
62
|
*
|
59
|
|
- * --
|
60
|
|
- *
|
61
|
|
- * The fast inverse function needed for Bézier interpolation for AVR
|
62
|
|
- * was designed, written and tested by Eduardo José Tagle on April/2018
|
|
63
|
+ * d1 -> (m^2 - s1^2) / (2 a)
|
|
64
|
+ * d2 -> (m^2 - s2^2) / (2 a)
|
|
65
|
+ * di -> (d + d1 - d2) / 2
|
63
|
66
|
*/
|
64
|
67
|
|
65
|
68
|
#include "planner.h"
|
|
@@ -211,7 +214,7 @@ xyze_long_t Planner::position{0};
|
211
|
214
|
uint32_t Planner::acceleration_long_cutoff;
|
212
|
215
|
|
213
|
216
|
xyze_float_t Planner::previous_speed;
|
214
|
|
-float Planner::previous_nominal_speed_sqr;
|
|
217
|
+float Planner::previous_nominal_speed;
|
215
|
218
|
|
216
|
219
|
#if ENABLED(DISABLE_INACTIVE_EXTRUDER)
|
217
|
220
|
last_move_t Planner::g_uc_extruder_last_move[E_STEPPERS] = { 0 };
|
|
@@ -220,7 +223,7 @@ float Planner::previous_nominal_speed_sqr;
|
220
|
223
|
#ifdef XY_FREQUENCY_LIMIT
|
221
|
224
|
int8_t Planner::xy_freq_limit_hz = XY_FREQUENCY_LIMIT;
|
222
|
225
|
float Planner::xy_freq_min_speed_factor = (XY_FREQUENCY_MIN_PERCENT) * 0.01f;
|
223
|
|
- int32_t Planner::xy_freq_min_interval_us = LROUND(1000000.0 / (XY_FREQUENCY_LIMIT));
|
|
226
|
+ int32_t Planner::xy_freq_min_interval_us = LROUND(1000000.0f / (XY_FREQUENCY_LIMIT));
|
224
|
227
|
#endif
|
225
|
228
|
|
226
|
229
|
#if ENABLED(LIN_ADVANCE)
|
|
@@ -250,7 +253,7 @@ void Planner::init() {
|
250
|
253
|
TERN_(HAS_POSITION_FLOAT, position_float.reset());
|
251
|
254
|
TERN_(IS_KINEMATIC, position_cart.reset());
|
252
|
255
|
previous_speed.reset();
|
253
|
|
- previous_nominal_speed_sqr = 0;
|
|
256
|
+ previous_nominal_speed = 0;
|
254
|
257
|
TERN_(ABL_PLANAR, bed_level_matrix.set_to_identity());
|
255
|
258
|
clear_block_buffer();
|
256
|
259
|
delay_before_delivering = 0;
|
|
@@ -786,41 +789,48 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
|
786
|
789
|
NOLESS(final_rate, uint32_t(MINIMAL_STEP_RATE));
|
787
|
790
|
|
788
|
791
|
#if ENABLED(S_CURVE_ACCELERATION)
|
789
|
|
- uint32_t cruise_rate = initial_rate;
|
|
792
|
+ // If we have some plateau time, the cruise rate will be the nominal rate
|
|
793
|
+ uint32_t cruise_rate = block->nominal_rate;
|
790
|
794
|
#endif
|
791
|
795
|
|
792
|
796
|
const int32_t accel = block->acceleration_steps_per_s2;
|
793
|
797
|
|
794
|
|
- // Steps required for acceleration, deceleration to/from nominal rate
|
795
|
|
- uint32_t accelerate_steps = CEIL(estimate_acceleration_distance(initial_rate, block->nominal_rate, accel)),
|
796
|
|
- decelerate_steps = FLOOR(estimate_acceleration_distance(block->nominal_rate, final_rate, -accel));
|
797
|
|
- // Steps between acceleration and deceleration, if any
|
798
|
|
- int32_t plateau_steps = block->step_event_count - accelerate_steps - decelerate_steps;
|
799
|
|
-
|
800
|
|
- // Does accelerate_steps + decelerate_steps exceed step_event_count?
|
801
|
|
- // Then we can't possibly reach the nominal rate, there will be no cruising.
|
802
|
|
- // Use intersection_distance() to calculate accel / braking time in order to
|
803
|
|
- // reach the final_rate exactly at the end of this block.
|
804
|
|
- if (plateau_steps < 0) {
|
805
|
|
- const float accelerate_steps_float = CEIL(intersection_distance(initial_rate, final_rate, accel, block->step_event_count));
|
806
|
|
- accelerate_steps = _MIN(uint32_t(_MAX(accelerate_steps_float, 0)), block->step_event_count);
|
807
|
|
- decelerate_steps = block->step_event_count - accelerate_steps;
|
808
|
|
- plateau_steps = 0;
|
809
|
|
-
|
810
|
|
- #if ENABLED(S_CURVE_ACCELERATION)
|
811
|
|
- // We won't reach the cruising rate. Let's calculate the speed we will reach
|
812
|
|
- cruise_rate = final_speed(initial_rate, accel, accelerate_steps);
|
813
|
|
- #endif
|
|
798
|
+ // Steps for acceleration, plateau and deceleration
|
|
799
|
+ int32_t plateau_steps = block->step_event_count;
|
|
800
|
+ uint32_t accelerate_steps = 0,
|
|
801
|
+ decelerate_steps = 0;
|
|
802
|
+
|
|
803
|
+ if (accel != 0) {
|
|
804
|
+ // Steps required for acceleration, deceleration to/from nominal rate
|
|
805
|
+ const float nominal_rate_sq = sq(float(block->nominal_rate));
|
|
806
|
+ float accelerate_steps_float = (nominal_rate_sq - sq(float(initial_rate))) * (0.5f / accel);
|
|
807
|
+ accelerate_steps = CEIL(accelerate_steps_float);
|
|
808
|
+ const float decelerate_steps_float = (nominal_rate_sq - sq(float(final_rate))) * (0.5f / accel);
|
|
809
|
+ decelerate_steps = decelerate_steps_float;
|
|
810
|
+
|
|
811
|
+ // Steps between acceleration and deceleration, if any
|
|
812
|
+ plateau_steps -= accelerate_steps + decelerate_steps;
|
|
813
|
+
|
|
814
|
+ // Does accelerate_steps + decelerate_steps exceed step_event_count?
|
|
815
|
+ // Then we can't possibly reach the nominal rate, there will be no cruising.
|
|
816
|
+ // Calculate accel / braking time in order to reach the final_rate exactly
|
|
817
|
+ // at the end of this block.
|
|
818
|
+ if (plateau_steps < 0) {
|
|
819
|
+ accelerate_steps_float = CEIL((block->step_event_count + accelerate_steps_float - decelerate_steps_float) * 0.5f);
|
|
820
|
+ accelerate_steps = _MIN(uint32_t(_MAX(accelerate_steps_float, 0)), block->step_event_count);
|
|
821
|
+ decelerate_steps = block->step_event_count - accelerate_steps;
|
|
822
|
+
|
|
823
|
+ #if ENABLED(S_CURVE_ACCELERATION)
|
|
824
|
+ // We won't reach the cruising rate. Let's calculate the speed we will reach
|
|
825
|
+ cruise_rate = final_speed(initial_rate, accel, accelerate_steps);
|
|
826
|
+ #endif
|
|
827
|
+ }
|
814
|
828
|
}
|
815
|
|
- #if ENABLED(S_CURVE_ACCELERATION)
|
816
|
|
- else // We have some plateau time, so the cruise rate will be the nominal rate
|
817
|
|
- cruise_rate = block->nominal_rate;
|
818
|
|
- #endif
|
819
|
829
|
|
820
|
830
|
#if ENABLED(S_CURVE_ACCELERATION)
|
821
|
831
|
// Jerk controlled speed requires to express speed versus time, NOT steps
|
822
|
|
- uint32_t acceleration_time = ((float)(cruise_rate - initial_rate) / accel) * (STEPPER_TIMER_RATE),
|
823
|
|
- deceleration_time = ((float)(cruise_rate - final_rate) / accel) * (STEPPER_TIMER_RATE),
|
|
832
|
+ uint32_t acceleration_time = (float(cruise_rate - initial_rate) / accel) * (STEPPER_TIMER_RATE),
|
|
833
|
+ deceleration_time = (float(cruise_rate - final_rate) / accel) * (STEPPER_TIMER_RATE),
|
824
|
834
|
// And to offload calculations from the ISR, we also calculate the inverse of those times here
|
825
|
835
|
acceleration_time_inverse = get_period_inverse(acceleration_time),
|
826
|
836
|
deceleration_time_inverse = get_period_inverse(deceleration_time);
|
|
@@ -1175,7 +1185,7 @@ void Planner::recalculate_trapezoids(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t
|
1175
|
1185
|
|
1176
|
1186
|
// Go from the tail (currently executed block) to the first block, without including it)
|
1177
|
1187
|
block_t *block = nullptr, *next = nullptr;
|
1178
|
|
- float current_entry_speed = 0.0, next_entry_speed = 0.0;
|
|
1188
|
+ float current_entry_speed = 0.0f, next_entry_speed = 0.0f;
|
1179
|
1189
|
while (block_index != head_block_index) {
|
1180
|
1190
|
|
1181
|
1191
|
next = &block_buffer[block_index];
|
|
@@ -1199,13 +1209,12 @@ void Planner::recalculate_trapezoids(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t
|
1199
|
1209
|
// Block is not BUSY, we won the race against the Stepper ISR:
|
1200
|
1210
|
|
1201
|
1211
|
// NOTE: Entry and exit factors always > 0 by all previous logic operations.
|
1202
|
|
- const float current_nominal_speed = SQRT(block->nominal_speed_sqr),
|
1203
|
|
- nomr = 1.0f / current_nominal_speed;
|
|
1212
|
+ const float nomr = 1.0f / block->nominal_speed;
|
1204
|
1213
|
calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
|
1205
|
1214
|
#if ENABLED(LIN_ADVANCE)
|
1206
|
1215
|
if (block->use_advance_lead) {
|
1207
|
1216
|
const float comp = block->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
|
1208
|
|
- block->max_adv_steps = current_nominal_speed * comp;
|
|
1217
|
+ block->max_adv_steps = block->nominal_speed * comp;
|
1209
|
1218
|
block->final_adv_steps = next_entry_speed * comp;
|
1210
|
1219
|
}
|
1211
|
1220
|
#endif
|
|
@@ -1240,13 +1249,12 @@ void Planner::recalculate_trapezoids(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t
|
1240
|
1249
|
if (!stepper.is_block_busy(block)) {
|
1241
|
1250
|
// Block is not BUSY, we won the race against the Stepper ISR:
|
1242
|
1251
|
|
1243
|
|
- const float current_nominal_speed = SQRT(block->nominal_speed_sqr),
|
1244
|
|
- nomr = 1.0f / current_nominal_speed;
|
|
1252
|
+ const float nomr = 1.0f / block->nominal_speed;
|
1245
|
1253
|
calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
|
1246
|
1254
|
#if ENABLED(LIN_ADVANCE)
|
1247
|
1255
|
if (block->use_advance_lead) {
|
1248
|
1256
|
const float comp = block->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
|
1249
|
|
- block->max_adv_steps = current_nominal_speed * comp;
|
|
1257
|
+ block->max_adv_steps = block->nominal_speed * comp;
|
1250
|
1258
|
block->final_adv_steps = next_entry_speed * comp;
|
1251
|
1259
|
}
|
1252
|
1260
|
#endif
|
|
@@ -1290,14 +1298,10 @@ void Planner::recalculate(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t safe_exit_s
|
1290
|
1298
|
#define FAN_SET(F) do{ kickstart_fan(fan_speed, ms, F); _FAN_SET(F); }while(0)
|
1291
|
1299
|
|
1292
|
1300
|
const millis_t ms = millis();
|
1293
|
|
- TERN_(HAS_FAN0, FAN_SET(0));
|
1294
|
|
- TERN_(HAS_FAN1, FAN_SET(1));
|
1295
|
|
- TERN_(HAS_FAN2, FAN_SET(2));
|
1296
|
|
- TERN_(HAS_FAN3, FAN_SET(3));
|
1297
|
|
- TERN_(HAS_FAN4, FAN_SET(4));
|
1298
|
|
- TERN_(HAS_FAN5, FAN_SET(5));
|
1299
|
|
- TERN_(HAS_FAN6, FAN_SET(6));
|
1300
|
|
- TERN_(HAS_FAN7, FAN_SET(7));
|
|
1301
|
+ TERN_(HAS_FAN0, FAN_SET(0)); TERN_(HAS_FAN1, FAN_SET(1));
|
|
1302
|
+ TERN_(HAS_FAN2, FAN_SET(2)); TERN_(HAS_FAN3, FAN_SET(3));
|
|
1303
|
+ TERN_(HAS_FAN4, FAN_SET(4)); TERN_(HAS_FAN5, FAN_SET(5));
|
|
1304
|
+ TERN_(HAS_FAN6, FAN_SET(6)); TERN_(HAS_FAN7, FAN_SET(7));
|
1301
|
1305
|
}
|
1302
|
1306
|
|
1303
|
1307
|
#if FAN_KICKSTART_TIME
|
|
@@ -1485,7 +1489,7 @@ void Planner::check_axes_activity() {
|
1485
|
1489
|
for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
|
1486
|
1490
|
const block_t * const block = &block_buffer[b];
|
1487
|
1491
|
if (NUM_AXIS_GANG(block->steps.x, || block->steps.y, || block->steps.z, || block->steps.i, || block->steps.j, || block->steps.k, || block->steps.u, || block->steps.v, || block->steps.w)) {
|
1488
|
|
- const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
|
|
1492
|
+ const float se = float(block->steps.e) / block->step_event_count * block->nominal_speed; // mm/sec
|
1489
|
1493
|
NOLESS(high, se);
|
1490
|
1494
|
}
|
1491
|
1495
|
}
|
|
@@ -1936,7 +1940,7 @@ bool Planner::_populate_block(
|
1936
|
1940
|
#if ENABLED(MIXING_EXTRUDER)
|
1937
|
1941
|
bool ignore_e = false;
|
1938
|
1942
|
float collector[MIXING_STEPPERS];
|
1939
|
|
- mixer.refresh_collector(1.0, mixer.get_current_vtool(), collector);
|
|
1943
|
+ mixer.refresh_collector(1.0f, mixer.get_current_vtool(), collector);
|
1940
|
1944
|
MIXER_STEPPER_LOOP(e)
|
1941
|
1945
|
if (e_steps * collector[e] > max_e_steps) { ignore_e = true; break; }
|
1942
|
1946
|
#else
|
|
@@ -2193,7 +2197,7 @@ bool Planner::_populate_block(
|
2193
|
2197
|
#if SECONDARY_LINEAR_AXES >= 1 && NONE(FOAMCUTTER_XYUV, ARTICULATED_ROBOT_ARM)
|
2194
|
2198
|
if (NEAR_ZERO(distance_sqr)) {
|
2195
|
2199
|
// Move does not involve any primary linear axes (xyz) but might involve secondary linear axes
|
2196
|
|
- distance_sqr = (0.0
|
|
2200
|
+ distance_sqr = (0.0f
|
2197
|
2201
|
SECONDARY_AXIS_GANG(
|
2198
|
2202
|
IF_DISABLED(AXIS4_ROTATES, + sq(steps_dist_mm.i)),
|
2199
|
2203
|
IF_DISABLED(AXIS5_ROTATES, + sq(steps_dist_mm.j)),
|
|
@@ -2396,7 +2400,7 @@ bool Planner::_populate_block(
|
2396
|
2400
|
if (was_enabled) stepper.wake_up();
|
2397
|
2401
|
#endif
|
2398
|
2402
|
|
2399
|
|
- block->nominal_speed_sqr = sq(block->millimeters * inverse_secs); // (mm/sec)^2 Always > 0
|
|
2403
|
+ block->nominal_speed = block->millimeters * inverse_secs; // (mm/sec) Always > 0
|
2400
|
2404
|
block->nominal_rate = CEIL(block->step_event_count * inverse_secs); // (step/sec) Always > 0
|
2401
|
2405
|
|
2402
|
2406
|
#if ENABLED(FILAMENT_WIDTH_SENSOR)
|
|
@@ -2492,7 +2496,7 @@ bool Planner::_populate_block(
|
2492
|
2496
|
if (speed_factor < 1.0f) {
|
2493
|
2497
|
current_speed *= speed_factor;
|
2494
|
2498
|
block->nominal_rate *= speed_factor;
|
2495
|
|
- block->nominal_speed_sqr = block->nominal_speed_sqr * sq(speed_factor);
|
|
2499
|
+ block->nominal_speed *= speed_factor;
|
2496
|
2500
|
}
|
2497
|
2501
|
|
2498
|
2502
|
// Compute and limit the acceleration rate for the trapezoid generator.
|
|
@@ -2592,7 +2596,7 @@ bool Planner::_populate_block(
|
2592
|
2596
|
if (block->use_advance_lead) {
|
2593
|
2597
|
block->advance_speed = (STEPPER_TIMER_RATE) / (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * settings.axis_steps_per_mm[E_AXIS_N(extruder)]);
|
2594
|
2598
|
#if ENABLED(LA_DEBUG)
|
2595
|
|
- if (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * 2 < SQRT(block->nominal_speed_sqr) * block->e_D_ratio)
|
|
2599
|
+ if (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * 2 < block->nominal_speed * block->e_D_ratio)
|
2596
|
2600
|
SERIAL_ECHOLNPGM("More than 2 steps per eISR loop executed.");
|
2597
|
2601
|
if (block->advance_speed < 200)
|
2598
|
2602
|
SERIAL_ECHOLNPGM("eISR running at > 10kHz.");
|
|
@@ -2663,7 +2667,7 @@ bool Planner::_populate_block(
|
2663
|
2667
|
unit_vec *= inverse_millimeters; // Use pre-calculated (1 / SQRT(x^2 + y^2 + z^2))
|
2664
|
2668
|
|
2665
|
2669
|
// Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles.
|
2666
|
|
- if (moves_queued && !UNEAR_ZERO(previous_nominal_speed_sqr)) {
|
|
2670
|
+ if (moves_queued && !UNEAR_ZERO(previous_nominal_speed)) {
|
2667
|
2671
|
// Compute cosine of angle between previous and current path. (prev_unit_vec is negative)
|
2668
|
2672
|
// NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity.
|
2669
|
2673
|
float junction_cos_theta = LOGICAL_AXIS_GANG(
|
|
@@ -2792,7 +2796,7 @@ bool Planner::_populate_block(
|
2792
|
2796
|
}
|
2793
|
2797
|
|
2794
|
2798
|
// Get the lowest speed
|
2795
|
|
- vmax_junction_sqr = _MIN(vmax_junction_sqr, block->nominal_speed_sqr, previous_nominal_speed_sqr);
|
|
2799
|
+ vmax_junction_sqr = _MIN(vmax_junction_sqr, sq(block->nominal_speed), sq(previous_nominal_speed));
|
2796
|
2800
|
}
|
2797
|
2801
|
else // Init entry speed to zero. Assume it starts from rest. Planner will correct this later.
|
2798
|
2802
|
vmax_junction_sqr = 0;
|
|
@@ -2801,27 +2805,17 @@ bool Planner::_populate_block(
|
2801
|
2805
|
|
2802
|
2806
|
#endif
|
2803
|
2807
|
|
2804
|
|
- #ifdef USE_CACHED_SQRT
|
2805
|
|
- #define CACHED_SQRT(N, V) \
|
2806
|
|
- static float saved_V, N; \
|
2807
|
|
- if (V != saved_V) { N = SQRT(V); saved_V = V; }
|
2808
|
|
- #else
|
2809
|
|
- #define CACHED_SQRT(N, V) const float N = SQRT(V)
|
2810
|
|
- #endif
|
2811
|
|
-
|
2812
|
2808
|
#if HAS_CLASSIC_JERK
|
2813
|
2809
|
|
2814
|
2810
|
/**
|
2815
|
2811
|
* Adapted from Průša MKS firmware
|
2816
|
2812
|
* https://github.com/prusa3d/Prusa-Firmware
|
2817
|
2813
|
*/
|
2818
|
|
- CACHED_SQRT(nominal_speed, block->nominal_speed_sqr);
|
2819
|
|
-
|
2820
|
2814
|
// Exit speed limited by a jerk to full halt of a previous last segment
|
2821
|
2815
|
static float previous_safe_speed;
|
2822
|
2816
|
|
2823
|
2817
|
// Start with a safe speed (from which the machine may halt to stop immediately).
|
2824
|
|
- float safe_speed = nominal_speed;
|
|
2818
|
+ float safe_speed = block->nominal_speed;
|
2825
|
2819
|
|
2826
|
2820
|
#ifndef TRAVEL_EXTRA_XYJERK
|
2827
|
2821
|
#define TRAVEL_EXTRA_XYJERK 0
|
|
@@ -2834,7 +2828,7 @@ bool Planner::_populate_block(
|
2834
|
2828
|
maxj = (max_jerk[i] + (i == X_AXIS || i == Y_AXIS ? extra_xyjerk : 0.0f)); // mj : The max jerk setting for this axis
|
2835
|
2829
|
if (jerk > maxj) { // cs > mj : New current speed too fast?
|
2836
|
2830
|
if (limited) { // limited already?
|
2837
|
|
- const float mjerk = nominal_speed * maxj; // ns*mj
|
|
2831
|
+ const float mjerk = block->nominal_speed * maxj; // ns*mj
|
2838
|
2832
|
if (jerk * safe_speed > mjerk) safe_speed = mjerk / jerk; // ns*mj/cs
|
2839
|
2833
|
}
|
2840
|
2834
|
else {
|
|
@@ -2845,7 +2839,7 @@ bool Planner::_populate_block(
|
2845
|
2839
|
}
|
2846
|
2840
|
|
2847
|
2841
|
float vmax_junction;
|
2848
|
|
- if (moves_queued && !UNEAR_ZERO(previous_nominal_speed_sqr)) {
|
|
2842
|
+ if (moves_queued && !UNEAR_ZERO(previous_nominal_speed)) {
|
2849
|
2843
|
// Estimate a maximum velocity allowed at a joint of two successive segments.
|
2850
|
2844
|
// If this maximum velocity allowed is lower than the minimum of the entry / exit safe velocities,
|
2851
|
2845
|
// then the machine is not coasting anymore and the safe entry / exit velocities shall be used.
|
|
@@ -2856,11 +2850,9 @@ bool Planner::_populate_block(
|
2856
|
2850
|
|
2857
|
2851
|
// The junction velocity will be shared between successive segments. Limit the junction velocity to their minimum.
|
2858
|
2852
|
// Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting.
|
2859
|
|
- CACHED_SQRT(previous_nominal_speed, previous_nominal_speed_sqr);
|
2860
|
|
-
|
2861
|
2853
|
float smaller_speed_factor = 1.0f;
|
2862
|
|
- if (nominal_speed < previous_nominal_speed) {
|
2863
|
|
- vmax_junction = nominal_speed;
|
|
2854
|
+ if (block->nominal_speed < previous_nominal_speed) {
|
|
2855
|
+ vmax_junction = block->nominal_speed;
|
2864
|
2856
|
smaller_speed_factor = vmax_junction / previous_nominal_speed;
|
2865
|
2857
|
}
|
2866
|
2858
|
else
|
|
@@ -2927,11 +2919,11 @@ bool Planner::_populate_block(
|
2927
|
2919
|
// block nominal speed limits both the current and next maximum junction speeds. Hence, in both
|
2928
|
2920
|
// the reverse and forward planners, the corresponding block junction speed will always be at the
|
2929
|
2921
|
// the maximum junction speed and may always be ignored for any speed reduction checks.
|
2930
|
|
- block->flag.set_nominal(block->nominal_speed_sqr <= v_allowable_sqr);
|
|
2922
|
+ block->flag.set_nominal(sq(block->nominal_speed) <= v_allowable_sqr);
|
2931
|
2923
|
|
2932
|
2924
|
// Update previous path unit_vector and nominal speed
|
2933
|
2925
|
previous_speed = current_speed;
|
2934
|
|
- previous_nominal_speed_sqr = block->nominal_speed_sqr;
|
|
2926
|
+ previous_nominal_speed = block->nominal_speed;
|
2935
|
2927
|
|
2936
|
2928
|
position = target; // Update the position
|
2937
|
2929
|
|
|
@@ -3268,7 +3260,7 @@ void Planner::set_machine_position_mm(const abce_pos_t &abce) {
|
3268
|
3260
|
);
|
3269
|
3261
|
|
3270
|
3262
|
if (has_blocks_queued()) {
|
3271
|
|
- //previous_nominal_speed_sqr = 0.0; // Reset planner junction speeds. Assume start from rest.
|
|
3263
|
+ //previous_nominal_speed = 0.0f; // Reset planner junction speeds. Assume start from rest.
|
3272
|
3264
|
//previous_speed.reset();
|
3273
|
3265
|
buffer_sync_block(BLOCK_BIT_SYNC_POSITION);
|
3274
|
3266
|
}
|
|
@@ -3344,7 +3336,7 @@ void Planner::refresh_positioning() {
|
3344
|
3336
|
inline void limit_and_warn(float &val, const AxisEnum axis, PGM_P const setting_name, const xyze_float_t &max_limit) {
|
3345
|
3337
|
const uint8_t lim_axis = TERN_(HAS_EXTRUDERS, axis > E_AXIS ? E_AXIS :) axis;
|
3346
|
3338
|
const float before = val;
|
3347
|
|
- LIMIT(val, 0.1, max_limit[lim_axis]);
|
|
3339
|
+ LIMIT(val, 0.1f, max_limit[lim_axis]);
|
3348
|
3340
|
if (before != val) {
|
3349
|
3341
|
SERIAL_CHAR(AXIS_CHAR(lim_axis));
|
3350
|
3342
|
SERIAL_ECHOPGM(" Max ");
|