Smarter MIN, MAX, ABS macros

Use macros that explicitly avoid double-evaluation and can be used for any datatype, replacing `min`, `max`, `abs`, `fabs`, `labs`, and `FABS`.

Co-Authored-By: ejtagle <ejtagle@hotmail.com>
This commit is contained in:
Scott Lahteine
2018-05-13 01:10:34 -05:00
parent 083ec9963e
commit 99ecdf59af
52 changed files with 206 additions and 247 deletions

View File

@ -134,7 +134,7 @@ void I2CPositionEncoder::update() {
#ifdef I2CPE_EC_THRESH_PROPORTIONAL
const millis_t deltaTime = positionTime - lastPositionTime;
const uint32_t distance = abs(position - lastPosition),
const uint32_t distance = ABS(position - lastPosition),
speed = distance / deltaTime;
const float threshold = constrain((speed / 50), 1, 50) * ecThreshold;
#else
@ -150,7 +150,7 @@ void I2CPositionEncoder::update() {
LOOP_L_N(i, I2CPE_ERR_ARRAY_SIZE) {
sum += err[i];
if (i) diffSum += abs(err[i-1] - err[i]);
if (i) diffSum += ABS(err[i-1] - err[i]);
}
const int32_t error = int32_t(sum / (I2CPE_ERR_ARRAY_SIZE + 1)); //calculate average for error
@ -163,7 +163,7 @@ void I2CPositionEncoder::update() {
//SERIAL_ECHOLN(error);
#ifdef I2CPE_ERR_THRESH_ABORT
if (labs(error) > I2CPE_ERR_THRESH_ABORT * planner.axis_steps_per_mm[encoderAxis]) {
if (ABS(error) > I2CPE_ERR_THRESH_ABORT * planner.axis_steps_per_mm[encoderAxis]) {
//kill("Significant Error");
SERIAL_ECHOPGM("Axis error greater than set threshold, aborting!");
SERIAL_ECHOLN(error);
@ -175,8 +175,8 @@ void I2CPositionEncoder::update() {
if (errIdx == 0) {
// In order to correct for "error" but avoid correcting for noise and non-skips
// it must be > threshold and have a difference average of < 10 and be < 2000 steps
if (labs(error) > threshold * planner.axis_steps_per_mm[encoderAxis] &&
diffSum < 10 * (I2CPE_ERR_ARRAY_SIZE - 1) && labs(error) < 2000) { // Check for persistent error (skip)
if (ABS(error) > threshold * planner.axis_steps_per_mm[encoderAxis] &&
diffSum < 10 * (I2CPE_ERR_ARRAY_SIZE - 1) && ABS(error) < 2000) { // Check for persistent error (skip)
errPrst[errPrstIdx++] = error; // Error must persist for I2CPE_ERR_PRST_ARRAY_SIZE error cycles. This also serves to improve the average accuracy
if (errPrstIdx >= I2CPE_ERR_PRST_ARRAY_SIZE) {
float sumP = 0;
@ -193,14 +193,14 @@ void I2CPositionEncoder::update() {
errPrstIdx = 0;
}
#else
if (labs(error) > threshold * planner.axis_steps_per_mm[encoderAxis]) {
if (ABS(error) > threshold * planner.axis_steps_per_mm[encoderAxis]) {
//SERIAL_ECHOLN(error);
//SERIAL_ECHOLN(position);
thermalManager.babystepsTodo[encoderAxis] = -LROUND(error / 2);
}
#endif
if (labs(error) > I2CPE_ERR_CNT_THRESH * planner.axis_steps_per_mm[encoderAxis]) {
if (ABS(error) > I2CPE_ERR_CNT_THRESH * planner.axis_steps_per_mm[encoderAxis]) {
const millis_t ms = millis();
if (ELAPSED(ms, nextErrorCountTime)) {
SERIAL_ECHOPAIR("Large error on ", axis_codes[encoderAxis]);
@ -258,7 +258,7 @@ float I2CPositionEncoder::get_axis_error_mm(const bool report) {
actual = mm_from_count(position);
error = actual - target;
if (labs(error) > 10000) error = 0; // ?
if (ABS(error) > 10000) error = 0; // ?
if (report) {
SERIAL_ECHO(axis_codes[encoderAxis]);
@ -293,7 +293,7 @@ int32_t I2CPositionEncoder::get_axis_error_steps(const bool report) {
error = (encoderCountInStepperTicksScaled - target);
//suppress discontinuities (might be caused by bad I2C readings...?)
bool suppressOutput = (labs(error - errorPrev) > 100);
bool suppressOutput = (ABS(error - errorPrev) > 100);
if (report) {
SERIAL_ECHO(axis_codes[encoderAxis]);
@ -435,7 +435,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
delay(250);
stopCount = get_position();
travelledDistance = mm_from_count(abs(stopCount - startCount));
travelledDistance = mm_from_count(ABS(stopCount - startCount));
SERIAL_ECHOPAIR("Attempted to travel: ", travelDistance);
SERIAL_ECHOLNPGM("mm.");

View File

@ -347,8 +347,8 @@ void Max7219_idle_tasks() {
NOMORE(current_depth, 16); // if the BLOCK_BUFFER_SIZE is greater than 16, two lines
// of LEDs is enough to see if the buffer is draining
const uint8_t st = min(current_depth, last_depth),
en = max(current_depth, last_depth);
const uint8_t st = MIN(current_depth, last_depth),
en = MAX(current_depth, last_depth);
if (current_depth < last_depth)
for (uint8_t i = st; i <= en; i++) // clear the highest order LEDs
Max7219_LED_Off(MAX7219_DEBUG_STEPPER_QUEUE + (i & 1), i / 2);

View File

@ -295,7 +295,7 @@ float bilinear_z_offset(const float raw[XYZ]) {
#endif
gridx = gx;
nextx = min(gridx + 1, ABL_BG_POINTS_X - 1);
nextx = MIN(gridx + 1, ABL_BG_POINTS_X - 1);
}
if (last_y != ry || last_gridx != gridx) {
@ -312,7 +312,7 @@ float bilinear_z_offset(const float raw[XYZ]) {
#endif
gridy = gy;
nexty = min(gridy + 1, ABL_BG_POINTS_Y - 1);
nexty = MIN(gridy + 1, ABL_BG_POINTS_Y - 1);
}
if (last_gridx != gridx || last_gridy != gridy) {
@ -336,7 +336,7 @@ float bilinear_z_offset(const float raw[XYZ]) {
/*
static float last_offset = 0;
if (FABS(last_offset - offset) > 0.2) {
if (ABS(last_offset - offset) > 0.2) {
SERIAL_ECHOPGM("Sudden Shift at ");
SERIAL_ECHOPAIR("x=", rx);
SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[X_AXIS]);
@ -389,7 +389,7 @@ float bilinear_z_offset(const float raw[XYZ]) {
#define LINE_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist)
float normalized_dist, end[XYZE];
const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
const int8_t gcx = MAX(cx1, cx2), gcy = MAX(cy1, cy2);
// Crosses on the X and not already split on this X?
// The x_splits flags are insurance against rounding errors.

View File

@ -76,7 +76,7 @@
#define MBL_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist)
float normalized_dist, end[XYZE];
const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
const int8_t gcx = MAX(cx1, cx2), gcy = MAX(cy1, cy2);
// Crosses on the X and not already split on this X?
// The x_splits flags are insurance against rounding errors.

View File

@ -242,7 +242,7 @@ class unified_bed_leveling {
const float xratio = (rx0 - mesh_index_to_xpos(x1_i)) * (1.0 / (MESH_X_DIST)),
z1 = z_values[x1_i][yi];
return z1 + xratio * (z_values[min(x1_i, GRID_MAX_POINTS_X - 2) + 1][yi] - z1); // Don't allow x1_i+1 to be past the end of the array
return z1 + xratio * (z_values[MIN(x1_i, GRID_MAX_POINTS_X - 2) + 1][yi] - z1); // Don't allow x1_i+1 to be past the end of the array
// If it is, it is clamped to the last element of the
// z_values[][] array and no correction is applied.
}
@ -276,7 +276,7 @@ class unified_bed_leveling {
const float yratio = (ry0 - mesh_index_to_ypos(y1_i)) * (1.0 / (MESH_Y_DIST)),
z1 = z_values[xi][y1_i];
return z1 + yratio * (z_values[xi][min(y1_i, GRID_MAX_POINTS_Y - 2) + 1] - z1); // Don't allow y1_i+1 to be past the end of the array
return z1 + yratio * (z_values[xi][MIN(y1_i, GRID_MAX_POINTS_Y - 2) + 1] - z1); // Don't allow y1_i+1 to be past the end of the array
// If it is, it is clamped to the last element of the
// z_values[][] array and no correction is applied.
}
@ -302,11 +302,11 @@ class unified_bed_leveling {
const float z1 = calc_z0(rx0,
mesh_index_to_xpos(cx), z_values[cx][cy],
mesh_index_to_xpos(cx + 1), z_values[min(cx, GRID_MAX_POINTS_X - 2) + 1][cy]);
mesh_index_to_xpos(cx + 1), z_values[MIN(cx, GRID_MAX_POINTS_X - 2) + 1][cy]);
const float z2 = calc_z0(rx0,
mesh_index_to_xpos(cx), z_values[cx][min(cy, GRID_MAX_POINTS_Y - 2) + 1],
mesh_index_to_xpos(cx + 1), z_values[min(cx, GRID_MAX_POINTS_X - 2) + 1][min(cy, GRID_MAX_POINTS_Y - 2) + 1]);
mesh_index_to_xpos(cx), z_values[cx][MIN(cy, GRID_MAX_POINTS_Y - 2) + 1],
mesh_index_to_xpos(cx + 1), z_values[MIN(cx, GRID_MAX_POINTS_X - 2) + 1][MIN(cy, GRID_MAX_POINTS_Y - 2) + 1]);
float z0 = calc_z0(ry0,
mesh_index_to_ypos(cy), z1,

View File

@ -451,7 +451,7 @@
if (parser.seen('B')) {
g29_card_thickness = parser.has_value() ? parser.value_float() : measure_business_card_thickness((float) Z_CLEARANCE_BETWEEN_PROBES);
if (FABS(g29_card_thickness) > 1.5) {
if (ABS(g29_card_thickness) > 1.5) {
SERIAL_PROTOCOLLNPGM("?Error in Business Card measurement.");
return;
}
@ -796,7 +796,7 @@
save_ubl_active_state_and_disable(); // Disable bed level correction for probing
do_blocking_move_to(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y)), in_height);
//, min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS]) / 2.0);
//, MIN(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS]) / 2.0);
planner.synchronize();
SERIAL_PROTOCOLPGM("Place shim under nozzle");
@ -816,7 +816,7 @@
do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES);
const float thickness = abs(z1 - z2);
const float thickness = ABS(z1 - z2);
if (g29_verbose_level > 1) {
SERIAL_PROTOCOLPGM("Business Card is ");
@ -1499,10 +1499,10 @@
#include "../../../libs/vector_3.h"
void unified_bed_leveling::tilt_mesh_based_on_probed_grid(const bool do_3_pt_leveling) {
constexpr int16_t x_min = max(MIN_PROBE_X, MESH_MIN_X),
x_max = min(MAX_PROBE_X, MESH_MAX_X),
y_min = max(MIN_PROBE_Y, MESH_MIN_Y),
y_max = min(MAX_PROBE_Y, MESH_MAX_Y);
constexpr int16_t x_min = MAX(MIN_PROBE_X, MESH_MIN_X),
x_max = MIN(MAX_PROBE_X, MESH_MAX_X),
y_min = MAX(MIN_PROBE_Y, MESH_MIN_Y),
y_max = MIN(MAX_PROBE_Y, MESH_MAX_Y);
bool abort_flag = false;
@ -1770,7 +1770,7 @@
SERIAL_ECHOPGM("Extrapolating mesh...");
const float weight_scaled = weight_factor * max(MESH_X_DIST, MESH_Y_DIST);
const float weight_scaled = weight_factor * MAX(MESH_X_DIST, MESH_Y_DIST);
for (uint8_t jx = 0; jx < GRID_MAX_POINTS_X; jx++)
for (uint8_t jy = 0; jy < GRID_MAX_POINTS_Y; jy++)

View File

@ -387,11 +387,11 @@
inverse_kinematics(raw); // this writes delta[ABC] from raw[XYZE]
// should move the feedrate scaling to scara inverse_kinematics
const float adiff = FABS(delta[A_AXIS] - scara_oldA),
bdiff = FABS(delta[B_AXIS] - scara_oldB);
const float adiff = ABS(delta[A_AXIS] - scara_oldA),
bdiff = ABS(delta[B_AXIS] - scara_oldB);
scara_oldA = delta[A_AXIS];
scara_oldB = delta[B_AXIS];
float s_feedrate = max(adiff, bdiff) * scara_feed_factor;
float s_feedrate = MAX(adiff, bdiff) * scara_feed_factor;
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], s_feedrate, active_extruder);

View File

@ -87,7 +87,7 @@ static void i2c_send(const uint8_t channel, const byte v) {
// This is for the MCP4018 I2C based digipot
void digipot_i2c_set_current(const uint8_t channel, const float current) {
i2c_send(channel, current_to_wiper(min(max(current, 0.0f), float(DIGIPOT_A4988_MAX_CURRENT))));
i2c_send(channel, current_to_wiper(MIN(MAX(current, 0.0f), float(DIGIPOT_A4988_MAX_CURRENT))));
}
void digipot_i2c_init() {

View File

@ -69,7 +69,7 @@ void digipot_i2c_set_current(const uint8_t channel, const float current) {
// Set actual wiper value
byte addresses[4] = { 0x00, 0x10, 0x60, 0x70 };
i2c_send(addr, addresses[channel & 0x3], current_to_wiper(min((float) max(current, 0.0f), DIGIPOT_I2C_MAX_CURRENT)));
i2c_send(addr, addresses[channel & 0x3], current_to_wiper(MIN((float) MAX(current, 0.0f), DIGIPOT_I2C_MAX_CURRENT)));
}
void digipot_i2c_init() {