Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize planner with precalculation, etc. #4389

Merged
merged 6 commits into from
Jul 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions Marlin/Marlin_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,20 @@ static void report_current_position();
print_xyz(PSTR(STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); } while(0)
#endif

/**
* sync_plan_position
* Set planner / stepper positions to the cartesian current_position.
* The stepper code translates these coordinates into step units.
* Allows translation between steps and millimeters for cartesian & core robots
*/
inline void sync_plan_position() {
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position", current_position);
#endif
planner.set_position_mm(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
}
inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); }

#if ENABLED(DELTA) || ENABLED(SCARA)
inline void sync_plan_position_delta() {
#if ENABLED(DEBUG_LEVELING_FEATURE)
Expand Down Expand Up @@ -897,16 +911,15 @@ void setup() {
// Send "ok" after commands by default
for (int8_t i = 0; i < BUFSIZE; i++) send_ok[i] = true;

// loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
// Load data from EEPROM if available (or use defaults)
// This also updates variables in the planner, elsewhere
Config_RetrieveSettings();

// Initialize current position based on home_offset
memcpy(current_position, home_offset, sizeof(home_offset));

#if ENABLED(DELTA) || ENABLED(SCARA)
// Vital to init kinematic equivalent for X0 Y0 Z0
SYNC_PLAN_POSITION_KINEMATIC();
#endif
// Vital to init stepper/planner equivalent for current_position
SYNC_PLAN_POSITION_KINEMATIC();

thermalManager.init(); // Initialize temperature loop

Expand Down Expand Up @@ -1319,7 +1332,7 @@ inline bool code_value_bool() { return code_value_byte() > 0; }
case TEMPUNIT_C:
return code_value_float();
case TEMPUNIT_F:
return (code_value_float() - 32) / 1.8;
return (code_value_float() - 32) * 0.5555555556;
case TEMPUNIT_K:
return code_value_float() - 272.15;
default:
Expand All @@ -1333,7 +1346,7 @@ inline bool code_value_bool() { return code_value_byte() > 0; }
case TEMPUNIT_K:
return code_value_float();
case TEMPUNIT_F:
return code_value_float() / 1.8;
return code_value_float() * 0.5555555556;
default:
return code_value_float();
}
Expand Down Expand Up @@ -1627,19 +1640,6 @@ inline void line_to_destination(float fr_mm_m) {
}
inline void line_to_destination() { line_to_destination(feedrate_mm_m); }

/**
* sync_plan_position
* Set planner / stepper positions to the cartesian current_position.
* The stepper code translates these coordinates into step units.
* Allows translation between steps and millimeters for cartesian & core robots
*/
inline void sync_plan_position() {
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position", current_position);
#endif
planner.set_position_mm(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
}
inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); }
inline void set_current_to_destination() { memcpy(current_position, destination, sizeof(current_position)); }
inline void set_destination_to_current() { memcpy(destination, current_position, sizeof(destination)); }

Expand Down Expand Up @@ -5147,6 +5147,7 @@ inline void gcode_M92() {
}
}
}
planner.refresh_positioning();
}

/**
Expand Down Expand Up @@ -6140,7 +6141,7 @@ inline void gcode_M428() {
bool err = false;
LOOP_XYZ(i) {
if (axis_homed[i]) {
float base = (current_position[i] > (sw_endstop_min[i] + sw_endstop_max[i]) / 2) ? base_home_pos(i) : 0,
float base = (current_position[i] > (sw_endstop_min[i] + sw_endstop_max[i]) * 0.5) ? base_home_pos(i) : 0,
diff = current_position[i] - LOGICAL_POSITION(base, i);
if (diff > -20 && diff < 20) {
set_home_offset((AxisEnum)i, home_offset[i] - diff);
Expand Down
6 changes: 6 additions & 0 deletions Marlin/configuration_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,16 @@ void Config_Postprocess() {
// steps per s2 needs to be updated to agree with units per s2
planner.reset_acceleration_rates();

// Make sure delta kinematics are updated before refreshing the
// planner position so the stepper counts will be set correctly.
#if ENABLED(DELTA)
recalc_delta_settings(delta_radius, delta_diagonal_rod);
#endif

// Refresh steps_to_mm with the reciprocal of axis_steps_per_mm
// and init stepper.count[], planner.position[] with current_position
planner.refresh_positioning();

#if ENABLED(PIDTEMP)
thermalManager.updatePID();
#endif
Expand Down
111 changes: 67 additions & 44 deletions Marlin/planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,39 +80,40 @@ block_t Planner::block_buffer[BLOCK_BUFFER_SIZE];
volatile uint8_t Planner::block_buffer_head = 0; // Index of the next block to be pushed
volatile uint8_t Planner::block_buffer_tail = 0;

float Planner::max_feedrate_mm_s[NUM_AXIS]; // Max speeds in mm per second
float Planner::axis_steps_per_mm[NUM_AXIS];
unsigned long Planner::max_acceleration_steps_per_s2[NUM_AXIS];
unsigned long Planner::max_acceleration_mm_per_s2[NUM_AXIS]; // Use M201 to override by software
float Planner::max_feedrate_mm_s[NUM_AXIS], // Max speeds in mm per second
Planner::axis_steps_per_mm[NUM_AXIS],
Planner::steps_to_mm[NUM_AXIS];

unsigned long Planner::max_acceleration_steps_per_s2[NUM_AXIS],
Planner::max_acceleration_mm_per_s2[NUM_AXIS]; // Use M201 to override by software

millis_t Planner::min_segment_time;
float Planner::min_feedrate_mm_s;
float Planner::acceleration; // Normal acceleration mm/s^2 DEFAULT ACCELERATION for all printing moves. M204 SXXXX
float Planner::retract_acceleration; // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX
float Planner::travel_acceleration; // Travel acceleration mm/s^2 DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX
float Planner::max_xy_jerk; // The largest speed change requiring no acceleration
float Planner::max_z_jerk;
float Planner::max_e_jerk;
float Planner::min_travel_feedrate_mm_s;
float Planner::min_feedrate_mm_s,
Planner::acceleration, // Normal acceleration mm/s^2 DEFAULT ACCELERATION for all printing moves. M204 SXXXX
Planner::retract_acceleration, // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX
Planner::travel_acceleration, // Travel acceleration mm/s^2 DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX
Planner::max_xy_jerk, // The largest speed change requiring no acceleration
Planner::max_z_jerk,
Planner::max_e_jerk,
Planner::min_travel_feedrate_mm_s;

#if ENABLED(AUTO_BED_LEVELING_FEATURE)
matrix_3x3 Planner::bed_level_matrix; // Transform to compensate for bed level
#endif

#if ENABLED(AUTOTEMP)
float Planner::autotemp_max = 250;
float Planner::autotemp_min = 210;
float Planner::autotemp_factor = 0.1;
float Planner::autotemp_max = 250,
Planner::autotemp_min = 210,
Planner::autotemp_factor = 0.1;
bool Planner::autotemp_enabled = false;
#endif

// private:

long Planner::position[NUM_AXIS] = { 0 };

float Planner::previous_speed[NUM_AXIS];

float Planner::previous_nominal_speed;
float Planner::previous_speed[NUM_AXIS],
Planner::previous_nominal_speed;

#if ENABLED(DISABLE_INACTIVE_EXTRUDER)
uint8_t Planner::g_uc_extruder_last_move[EXTRUDERS] = { 0 };
Expand Down Expand Up @@ -783,31 +784,37 @@ void Planner::check_axes_activity() {
#if ENABLED(COREXY) || ENABLED(COREXZ) || ENABLED(COREYZ)
float delta_mm[6];
#if ENABLED(COREXY)
delta_mm[X_HEAD] = dx / axis_steps_per_mm[A_AXIS];
delta_mm[Y_HEAD] = dy / axis_steps_per_mm[B_AXIS];
delta_mm[Z_AXIS] = dz / axis_steps_per_mm[Z_AXIS];
delta_mm[A_AXIS] = (dx + dy) / axis_steps_per_mm[A_AXIS];
delta_mm[B_AXIS] = (dx - dy) / axis_steps_per_mm[B_AXIS];
delta_mm[X_HEAD] = dx * steps_to_mm[A_AXIS];
delta_mm[Y_HEAD] = dy * steps_to_mm[B_AXIS];
delta_mm[Z_AXIS] = dz * steps_to_mm[Z_AXIS];
delta_mm[A_AXIS] = (dx + dy) * steps_to_mm[A_AXIS];
delta_mm[B_AXIS] = (dx - dy) * steps_to_mm[B_AXIS];
#elif ENABLED(COREXZ)
delta_mm[X_HEAD] = dx / axis_steps_per_mm[A_AXIS];
delta_mm[Y_AXIS] = dy / axis_steps_per_mm[Y_AXIS];
delta_mm[Z_HEAD] = dz / axis_steps_per_mm[C_AXIS];
delta_mm[A_AXIS] = (dx + dz) / axis_steps_per_mm[A_AXIS];
delta_mm[C_AXIS] = (dx - dz) / axis_steps_per_mm[C_AXIS];
delta_mm[X_HEAD] = dx * steps_to_mm[A_AXIS];
delta_mm[Y_AXIS] = dy * steps_to_mm[Y_AXIS];
delta_mm[Z_HEAD] = dz * steps_to_mm[C_AXIS];
delta_mm[A_AXIS] = (dx + dz) * steps_to_mm[A_AXIS];
delta_mm[C_AXIS] = (dx - dz) * steps_to_mm[C_AXIS];
#elif ENABLED(COREYZ)
delta_mm[X_AXIS] = dx / axis_steps_per_mm[A_AXIS];
delta_mm[Y_HEAD] = dy / axis_steps_per_mm[Y_AXIS];
delta_mm[Z_HEAD] = dz / axis_steps_per_mm[C_AXIS];
delta_mm[B_AXIS] = (dy + dz) / axis_steps_per_mm[B_AXIS];
delta_mm[C_AXIS] = (dy - dz) / axis_steps_per_mm[C_AXIS];
delta_mm[X_AXIS] = dx * steps_to_mm[X_AXIS];
delta_mm[Y_HEAD] = dy * steps_to_mm[B_AXIS];
delta_mm[Z_HEAD] = dz * steps_to_mm[C_AXIS];
delta_mm[B_AXIS] = (dy + dz) * steps_to_mm[B_AXIS];
delta_mm[C_AXIS] = (dy - dz) * steps_to_mm[C_AXIS];
#endif
#else
float delta_mm[4];
delta_mm[X_AXIS] = dx / axis_steps_per_mm[X_AXIS];
delta_mm[Y_AXIS] = dy / axis_steps_per_mm[Y_AXIS];
delta_mm[Z_AXIS] = dz / axis_steps_per_mm[Z_AXIS];
#if ENABLED(DELTA)
// On delta all axes (should!) have the same steps-per-mm
// so calculate distance in steps first, then do one division
// at the end to get millimeters
#else
delta_mm[X_AXIS] = dx * steps_to_mm[X_AXIS];
delta_mm[Y_AXIS] = dy * steps_to_mm[Y_AXIS];
delta_mm[Z_AXIS] = dz * steps_to_mm[Z_AXIS];
#endif
#endif
delta_mm[E_AXIS] = (de / axis_steps_per_mm[E_AXIS]) * volumetric_multiplier[extruder] * extruder_multiplier[extruder] / 100.0;
delta_mm[E_AXIS] = 0.01 * (de * steps_to_mm[E_AXIS]) * volumetric_multiplier[extruder] * extruder_multiplier[extruder];

if (block->steps[X_AXIS] <= dropsegments && block->steps[Y_AXIS] <= dropsegments && block->steps[Z_AXIS] <= dropsegments) {
block->millimeters = fabs(delta_mm[E_AXIS]);
Expand All @@ -820,10 +827,16 @@ void Planner::check_axes_activity() {
sq(delta_mm[X_HEAD]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_HEAD])
#elif ENABLED(COREYZ)
sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_HEAD]) + sq(delta_mm[Z_HEAD])
#elif ENABLED(DELTA)
sq(dx) + sq(dy) + sq(dz)
#else
sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_AXIS])
#endif
);
)
#if ENABLED(DELTA)
* steps_to_mm[X_AXIS]
#endif
;
}
float inverse_millimeters = 1.0 / block->millimeters; // Inverse millimeters to remove multiple divides

Expand Down Expand Up @@ -875,7 +888,7 @@ void Planner::check_axes_activity() {
while (filwidth_delay_dist >= MMD_MM) filwidth_delay_dist -= MMD_MM;

// Convert into an index into the measurement array
filwidth_delay_index1 = (int)(filwidth_delay_dist / 10.0 + 0.0001);
filwidth_delay_index1 = (int)(filwidth_delay_dist * 0.1 + 0.0001);

// If the index has changed (must have gone forward)...
if (filwidth_delay_index1 != filwidth_delay_index2) {
Expand Down Expand Up @@ -962,7 +975,7 @@ void Planner::check_axes_activity() {
block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[E_AXIS] * block->step_event_count) / block->steps[E_AXIS];
}
block->acceleration = block->acceleration_steps_per_s2 / steps_per_mm;
block->acceleration_rate = (long)(block->acceleration_steps_per_s2 * 16777216.0 / ((F_CPU) / 8.0));
block->acceleration_rate = (long)(block->acceleration_steps_per_s2 * 16777216.0 / ((F_CPU) * 0.125));

#if 0 // Use old jerk for now

Expand Down Expand Up @@ -1008,10 +1021,12 @@ void Planner::check_axes_activity() {
#endif

// Start with a safe speed
float vmax_junction = max_xy_jerk / 2;
float vmax_junction_factor = 1.0;
float mz2 = max_z_jerk / 2, me2 = max_e_jerk / 2;
float csz = current_speed[Z_AXIS], cse = current_speed[E_AXIS];
float vmax_junction = max_xy_jerk * 0.5,
vmax_junction_factor = 1.0,
mz2 = max_z_jerk * 0.5,
me2 = max_e_jerk * 0.5,
csz = current_speed[Z_AXIS],
cse = current_speed[E_AXIS];
if (fabs(csz) > mz2) vmax_junction = min(vmax_junction, mz2);
if (fabs(cse) > me2) vmax_junction = min(vmax_junction, me2);
vmax_junction = min(vmax_junction, block->nominal_speed);
Expand Down Expand Up @@ -1164,6 +1179,7 @@ void Planner::check_axes_activity() {
void Planner::set_e_position_mm(const float& e) {
position[E_AXIS] = lround(e * axis_steps_per_mm[E_AXIS]);
stepper.set_e_position(position[E_AXIS]);
previous_speed[E_AXIS] = 0.0;
}

// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
Expand All @@ -1172,6 +1188,13 @@ void Planner::reset_acceleration_rates() {
max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i];
}

// Recalculate position, steps_to_mm if axis_steps_per_mm changes!
void Planner::refresh_positioning() {
LOOP_XYZE(i) planner.steps_to_mm[i] = 1.0 / planner.axis_steps_per_mm[i];
set_position_mm(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
reset_acceleration_rates();
}

#if ENABLED(AUTOTEMP)

void Planner::autotemp_M109() {
Expand Down
4 changes: 3 additions & 1 deletion Marlin/planner.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class Planner {

static float max_feedrate_mm_s[NUM_AXIS]; // Max speeds in mm per second
static float axis_steps_per_mm[NUM_AXIS];
static float steps_to_mm[NUM_AXIS];
static unsigned long max_acceleration_steps_per_s2[NUM_AXIS];
static unsigned long max_acceleration_mm_per_s2[NUM_AXIS]; // Use M201 to override by software

Expand All @@ -142,7 +143,7 @@ class Planner {

/**
* The current position of the tool in absolute steps
* Reclculated if any axis_steps_per_mm are changed by gcode
* Recalculated if any axis_steps_per_mm are changed by gcode
*/
static long position[NUM_AXIS];

Expand Down Expand Up @@ -187,6 +188,7 @@ class Planner {
*/

static void reset_acceleration_rates();
static void refresh_positioning();

// Manage fans, paste pressure, etc.
static void check_axes_activity();
Expand Down
8 changes: 4 additions & 4 deletions Marlin/stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,14 +944,14 @@ float Stepper::get_axis_position_mm(AxisEnum axis) {
CRITICAL_SECTION_END;
// ((a1+a2)+(a1-a2))/2 -> (a1+a2+a1-a2)/2 -> (a1+a1)/2 -> a1
// ((a1+a2)-(a1-a2))/2 -> (a1+a2-a1+a2)/2 -> (a2+a2)/2 -> a2
axis_steps = (pos1 + ((axis == CORE_AXIS_1) ? pos2 : -pos2)) / 2.0f;
axis_steps = (pos1 + ((axis == CORE_AXIS_1) ? pos2 : -pos2)) * 0.5f;
}
else
axis_steps = position(axis);
#else
axis_steps = position(axis);
#endif
return axis_steps / planner.axis_steps_per_mm[axis];
return axis_steps * planner.steps_to_mm[axis];
}

void Stepper::finish_and_disable() {
Expand All @@ -973,9 +973,9 @@ void Stepper::endstop_triggered(AxisEnum axis) {

float axis_pos = count_position[axis];
if (axis == CORE_AXIS_1)
axis_pos = (axis_pos + count_position[CORE_AXIS_2]) / 2;
axis_pos = (axis_pos + count_position[CORE_AXIS_2]) * 0.5;
else if (axis == CORE_AXIS_2)
axis_pos = (count_position[CORE_AXIS_1] - axis_pos) / 2;
axis_pos = (count_position[CORE_AXIS_1] - axis_pos) * 0.5;
endstops_trigsteps[axis] = axis_pos;

#else // !COREXY && !COREXZ && !COREYZ
Expand Down
2 changes: 1 addition & 1 deletion Marlin/stepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ class Stepper {
// Triggered position of an axis in mm (not core-savvy)
//
static FORCE_INLINE float triggered_position_mm(AxisEnum axis) {
return endstops_trigsteps[axis] / planner.axis_steps_per_mm[axis];
return endstops_trigsteps[axis] * planner.steps_to_mm[axis];
}

#if ENABLED(LIN_ADVANCE)
Expand Down
Loading